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

Unified Diff: device/usb/usb_device_handle_impl.cc

Issue 980023002: Move device/usb classes from the FILE thread to UI thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: device/usb/usb_device_handle_impl.cc
diff --git a/device/usb/usb_device_handle_impl.cc b/device/usb/usb_device_handle_impl.cc
index fc14e82c30723f560ebb1a50ab29691d715c1c80..ff2582178aeef1e80efa28c88f30e1e548791c17 100644
--- a/device/usb/usb_device_handle_impl.cc
+++ b/device/usb/usb_device_handle_impl.cc
@@ -157,6 +157,7 @@ bool UsbDeviceHandleImpl::InterfaceClaimer::Claim() const {
class UsbDeviceHandleImpl::Transfer {
public:
static scoped_ptr<Transfer> CreateControlTransfer(
+ scoped_refptr<UsbDeviceHandleImpl> device_handle,
uint8 type,
uint8 request,
uint16 value,
@@ -164,62 +165,72 @@ class UsbDeviceHandleImpl::Transfer {
uint16 length,
scoped_refptr<net::IOBuffer> buffer,
unsigned int timeout,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
const UsbTransferCallback& callback);
static scoped_ptr<Transfer> CreateBulkTransfer(
+ scoped_refptr<UsbDeviceHandleImpl> device_handle,
uint8 endpoint,
scoped_refptr<net::IOBuffer> buffer,
int length,
unsigned int timeout,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
const UsbTransferCallback& callback);
static scoped_ptr<Transfer> CreateInterruptTransfer(
+ scoped_refptr<UsbDeviceHandleImpl> device_handle,
uint8 endpoint,
scoped_refptr<net::IOBuffer> buffer,
int length,
unsigned int timeout,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
const UsbTransferCallback& callback);
static scoped_ptr<Transfer> CreateIsochronousTransfer(
+ scoped_refptr<UsbDeviceHandleImpl> device_handle,
uint8 endpoint,
scoped_refptr<net::IOBuffer> buffer,
size_t length,
unsigned int packets,
unsigned int packet_length,
unsigned int timeout,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
const UsbTransferCallback& callback);
~Transfer();
- bool Submit(base::WeakPtr<UsbDeviceHandleImpl> device_handle);
+ void Submit();
void Cancel();
void ProcessCompletion();
- void Complete(UsbTransferStatus status, size_t bytes_transferred);
+ void TransferComplete(UsbTransferStatus status, size_t bytes_transferred);
const UsbDeviceHandleImpl::InterfaceClaimer* claimed_interface() const {
return claimed_interface_.get();
}
private:
- Transfer(UsbTransferType transfer_type,
+ Transfer(scoped_refptr<UsbDeviceHandleImpl> device_handle,
+ scoped_refptr<InterfaceClaimer> claimed_interface,
+ UsbTransferType transfer_type,
scoped_refptr<net::IOBuffer> buffer,
size_t length,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
const UsbTransferCallback& callback);
static void LIBUSB_CALL PlatformCallback(PlatformUsbTransferHandle handle);
UsbTransferType transfer_type_;
- base::WeakPtr<UsbDeviceHandleImpl> device_handle_;
+ scoped_refptr<UsbDeviceHandleImpl> device_handle_;
PlatformUsbTransferHandle platform_transfer_;
scoped_refptr<net::IOBuffer> buffer_;
scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface_;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
size_t length_;
bool cancelled_;
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
UsbTransferCallback callback_;
- scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner_;
};
// static
scoped_ptr<UsbDeviceHandleImpl::Transfer>
UsbDeviceHandleImpl::Transfer::CreateControlTransfer(
+ scoped_refptr<UsbDeviceHandleImpl> device_handle,
uint8 type,
uint8 request,
uint16 value,
@@ -227,10 +238,11 @@ UsbDeviceHandleImpl::Transfer::CreateControlTransfer(
uint16 length,
scoped_refptr<net::IOBuffer> buffer,
unsigned int timeout,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
const UsbTransferCallback& callback) {
- scoped_ptr<Transfer> transfer(new Transfer(USB_TRANSFER_CONTROL, buffer,
- length + LIBUSB_CONTROL_SETUP_SIZE,
- callback));
+ scoped_ptr<Transfer> transfer(
+ new Transfer(device_handle, nullptr, USB_TRANSFER_CONTROL, buffer,
+ length + LIBUSB_CONTROL_SETUP_SIZE, task_runner, callback));
transfer->platform_transfer_ = libusb_alloc_transfer(0);
if (!transfer->platform_transfer_) {
@@ -241,7 +253,7 @@ UsbDeviceHandleImpl::Transfer::CreateControlTransfer(
libusb_fill_control_setup(reinterpret_cast<uint8*>(buffer->data()), type,
request, value, index, length);
libusb_fill_control_transfer(transfer->platform_transfer_,
- nullptr, /* filled in by Submit() */
+ device_handle->handle_,
reinterpret_cast<uint8*>(buffer->data()),
&UsbDeviceHandleImpl::Transfer::PlatformCallback,
transfer.get(), timeout);
@@ -252,13 +264,16 @@ UsbDeviceHandleImpl::Transfer::CreateControlTransfer(
// static
scoped_ptr<UsbDeviceHandleImpl::Transfer>
UsbDeviceHandleImpl::Transfer::CreateBulkTransfer(
+ scoped_refptr<UsbDeviceHandleImpl> device_handle,
uint8 endpoint,
scoped_refptr<net::IOBuffer> buffer,
int length,
unsigned int timeout,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
const UsbTransferCallback& callback) {
- scoped_ptr<Transfer> transfer(
- new Transfer(USB_TRANSFER_BULK, buffer, length, callback));
+ scoped_ptr<Transfer> transfer(new Transfer(
+ device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint),
+ USB_TRANSFER_BULK, buffer, length, task_runner, callback));
transfer->platform_transfer_ = libusb_alloc_transfer(0);
if (!transfer->platform_transfer_) {
@@ -266,12 +281,11 @@ UsbDeviceHandleImpl::Transfer::CreateBulkTransfer(
return nullptr;
}
- libusb_fill_bulk_transfer(transfer->platform_transfer_,
- nullptr, /* filled in by Submit() */
- endpoint, reinterpret_cast<uint8*>(buffer->data()),
- static_cast<int>(length),
- &UsbDeviceHandleImpl::Transfer::PlatformCallback,
- transfer.get(), timeout);
+ libusb_fill_bulk_transfer(
+ transfer->platform_transfer_, device_handle->handle_, endpoint,
+ reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length),
+ &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(),
+ timeout);
return transfer.Pass();
}
@@ -279,13 +293,16 @@ UsbDeviceHandleImpl::Transfer::CreateBulkTransfer(
// static
scoped_ptr<UsbDeviceHandleImpl::Transfer>
UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer(
+ scoped_refptr<UsbDeviceHandleImpl> device_handle,
uint8 endpoint,
scoped_refptr<net::IOBuffer> buffer,
int length,
unsigned int timeout,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
const UsbTransferCallback& callback) {
- scoped_ptr<Transfer> transfer(
- new Transfer(USB_TRANSFER_INTERRUPT, buffer, length, callback));
+ scoped_ptr<Transfer> transfer(new Transfer(
+ device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint),
+ USB_TRANSFER_INTERRUPT, buffer, length, task_runner, callback));
transfer->platform_transfer_ = libusb_alloc_transfer(0);
if (!transfer->platform_transfer_) {
@@ -294,9 +311,8 @@ UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer(
}
libusb_fill_interrupt_transfer(
- transfer->platform_transfer_, nullptr, /* filled in by Submit() */
- endpoint, reinterpret_cast<uint8*>(buffer->data()),
- static_cast<int>(length),
+ transfer->platform_transfer_, device_handle->handle_, endpoint,
+ reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length),
&UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(),
timeout);
@@ -306,18 +322,21 @@ UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer(
// static
scoped_ptr<UsbDeviceHandleImpl::Transfer>
UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer(
+ scoped_refptr<UsbDeviceHandleImpl> device_handle,
uint8 endpoint,
scoped_refptr<net::IOBuffer> buffer,
size_t length,
unsigned int packets,
unsigned int packet_length,
unsigned int timeout,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
const UsbTransferCallback& callback) {
DCHECK(packets <= length && (packets * packet_length) <= length)
<< "transfer length is too small";
- scoped_ptr<Transfer> transfer(
- new Transfer(USB_TRANSFER_ISOCHRONOUS, buffer, length, callback));
+ scoped_ptr<Transfer> transfer(new Transfer(
+ device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint),
+ USB_TRANSFER_ISOCHRONOUS, buffer, length, task_runner, callback));
transfer->platform_transfer_ = libusb_alloc_transfer(packets);
if (!transfer->platform_transfer_) {
@@ -326,27 +345,31 @@ UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer(
}
libusb_fill_iso_transfer(
- transfer->platform_transfer_, nullptr, /* filled in by Submit() */
- endpoint, reinterpret_cast<uint8*>(buffer->data()),
- static_cast<int>(length), packets, &Transfer::PlatformCallback,
- transfer.get(), timeout);
+ transfer->platform_transfer_, device_handle->handle_, endpoint,
+ reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length),
+ packets, &Transfer::PlatformCallback, transfer.get(), timeout);
libusb_set_iso_packet_lengths(transfer->platform_transfer_, packet_length);
return transfer.Pass();
}
-UsbDeviceHandleImpl::Transfer::Transfer(UsbTransferType transfer_type,
- scoped_refptr<net::IOBuffer> buffer,
- size_t length,
- const UsbTransferCallback& callback)
+UsbDeviceHandleImpl::Transfer::Transfer(
+ scoped_refptr<UsbDeviceHandleImpl> device_handle,
+ scoped_refptr<InterfaceClaimer> claimed_interface,
+ UsbTransferType transfer_type,
+ scoped_refptr<net::IOBuffer> buffer,
+ size_t length,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
+ const UsbTransferCallback& callback)
: transfer_type_(transfer_type),
+ device_handle_(device_handle),
+ platform_transfer_(NULL),
buffer_(buffer),
+ claimed_interface_(claimed_interface),
length_(length),
cancelled_(false),
+ task_runner_(task_runner),
callback_(callback) {
- // Remember the thread from which this transfer was created so that |callback|
- // can be dispatched there.
- callback_task_runner_ = base::ThreadTaskRunnerHandle::Get();
}
UsbDeviceHandleImpl::Transfer::~Transfer() {
@@ -355,26 +378,12 @@ UsbDeviceHandleImpl::Transfer::~Transfer() {
}
}
-bool UsbDeviceHandleImpl::Transfer::Submit(
- base::WeakPtr<UsbDeviceHandleImpl> device_handle) {
- device_handle_ = device_handle;
- // Remember the thread from which this transfer was submitted so that it can
- // be marked complete there.
- task_runner_ = base::ThreadTaskRunnerHandle::Get();
- // GetClaimedInterfaceForEndpoint may return nullptr. libusb_submit_transfer
- // will fail if it requires an interface we didn't claim.
- claimed_interface_ = device_handle->GetClaimedInterfaceForEndpoint(
- platform_transfer_->endpoint);
- platform_transfer_->dev_handle = device_handle_->handle_;
-
+void UsbDeviceHandleImpl::Transfer::Submit() {
const int rv = libusb_submit_transfer(platform_transfer_);
- if (rv == LIBUSB_SUCCESS) {
- return true;
- } else {
+ if (rv != LIBUSB_SUCCESS) {
USB_LOG(EVENT) << "Failed to submit transfer: "
<< ConvertPlatformUsbErrorToString(rv);
- Complete(USB_TRANSFER_ERROR, 0);
- return false;
+ TransferComplete(USB_TRANSFER_ERROR, 0);
}
}
@@ -453,43 +462,38 @@ void UsbDeviceHandleImpl::Transfer::ProcessCompletion() {
break;
}
- Complete(ConvertTransferStatus(platform_transfer_->status), actual_length);
-}
-
-void UsbDeviceHandleImpl::Transfer::Complete(UsbTransferStatus status,
- size_t bytes_transferred) {
- if (callback_task_runner_->RunsTasksOnCurrentThread()) {
- callback_.Run(status, buffer_, bytes_transferred);
- } else {
- callback_task_runner_->PostTask(
- FROM_HERE, base::Bind(callback_, status, buffer_, bytes_transferred));
- }
+ TransferComplete(ConvertTransferStatus(platform_transfer_->status),
+ actual_length);
}
/* static */
void LIBUSB_CALL UsbDeviceHandleImpl::Transfer::PlatformCallback(
PlatformUsbTransferHandle platform_transfer) {
- scoped_ptr<Transfer> transfer(
- reinterpret_cast<Transfer*>(platform_transfer->user_data));
+ Transfer* transfer =
+ reinterpret_cast<Transfer*>(platform_transfer->user_data);
DCHECK(transfer->platform_transfer_ == platform_transfer);
+ transfer->ProcessCompletion();
+}
- // Because device_handle_ is a weak pointer it is guaranteed that the callback
- // will be discarded if the handle has been freed.
- Transfer* tmp_transfer = transfer.get(); // base::Passed invalidates transfer
- tmp_transfer->task_runner_->PostTask(
- FROM_HERE, base::Bind(&UsbDeviceHandleImpl::CompleteTransfer,
- tmp_transfer->device_handle_,
- base::Passed(&transfer)));
+void UsbDeviceHandleImpl::Transfer::TransferComplete(UsbTransferStatus status,
+ size_t bytes_transferred) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&UsbDeviceHandleImpl::TransferComplete, device_handle_,
+ base::Owned(this),
+ base::Bind(callback_, status, buffer_, bytes_transferred)));
}
-UsbDeviceHandleImpl::UsbDeviceHandleImpl(scoped_refptr<UsbContext> context,
- scoped_refptr<UsbDeviceImpl> device,
- PlatformUsbDeviceHandle handle)
+UsbDeviceHandleImpl::UsbDeviceHandleImpl(
+ scoped_refptr<UsbContext> context,
+ scoped_refptr<UsbDeviceImpl> device,
+ PlatformUsbDeviceHandle handle,
+ scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
: device_(device),
handle_(handle),
context_(context),
task_runner_(base::ThreadTaskRunnerHandle::Get()),
- weak_factory_(this) {
+ blocking_task_runner_(blocking_task_runner) {
DCHECK(handle) << "Cannot create device with NULL handle.";
}
@@ -510,10 +514,12 @@ void UsbDeviceHandleImpl::Close() {
device_->Close(this);
}
-bool UsbDeviceHandleImpl::SetConfiguration(int configuration_value) {
+void UsbDeviceHandleImpl::SetConfiguration(int configuration_value,
+ const UsbSuccessCallback& callback) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!device_) {
- return false;
+ task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+ return;
}
for (Transfer* transfer : transfers_) {
@@ -521,36 +527,31 @@ bool UsbDeviceHandleImpl::SetConfiguration(int configuration_value) {
}
claimed_interfaces_.clear();
- int rv = libusb_set_configuration(handle_, configuration_value);
- if (rv == LIBUSB_SUCCESS) {
- device_->RefreshConfiguration();
- RefreshEndpointMap();
- } else {
- USB_LOG(EVENT) << "Failed to set configuration " << configuration_value
- << ": " << ConvertPlatformUsbErrorToString(rv);
- }
- return rv == LIBUSB_SUCCESS;
+ blocking_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&UsbDeviceHandleImpl::SetConfigurationOnBlockingThread, this,
+ handle_, configuration_value, callback));
}
-bool UsbDeviceHandleImpl::ClaimInterface(const int interface_number) {
+void UsbDeviceHandleImpl::ClaimInterface(int interface_number,
+ const UsbSuccessCallback& callback) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (!device_)
- return false;
- if (ContainsKey(claimed_interfaces_, interface_number))
- return true;
-
- scoped_refptr<InterfaceClaimer> claimer =
- new InterfaceClaimer(this, interface_number);
-
- if (claimer->Claim()) {
- claimed_interfaces_[interface_number] = claimer;
- RefreshEndpointMap();
- return true;
+ if (!device_) {
+ task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+ return;
}
- return false;
+ if (ContainsKey(claimed_interfaces_, interface_number)) {
+ task_runner_->PostTask(FROM_HERE, base::Bind(callback, true));
Ken Rockot(use gerrit already) 2015/04/07 22:09:43 nit: Maybe it doesn't matter, but is there realist
Reilly Grant (use Gerrit) 2015/04/08 21:39:03 I'll change it because I've recently decided that
+ return;
+ }
+
+ blocking_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&UsbDeviceHandleImpl::ClaimInterfaceOnBlockingThread, this,
+ handle_, interface_number, callback));
}
-bool UsbDeviceHandleImpl::ReleaseInterface(const int interface_number) {
+bool UsbDeviceHandleImpl::ReleaseInterface(int interface_number) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!device_)
return false;
@@ -571,91 +572,33 @@ bool UsbDeviceHandleImpl::ReleaseInterface(const int interface_number) {
return true;
}
-bool UsbDeviceHandleImpl::SetInterfaceAlternateSetting(
- const int interface_number,
- const int alternate_setting) {
+void UsbDeviceHandleImpl::SetInterfaceAlternateSetting(
+ int interface_number,
+ int alternate_setting,
+ const UsbSuccessCallback& callback) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (!device_)
- return false;
- if (!ContainsKey(claimed_interfaces_, interface_number))
- return false;
- const int rv = libusb_set_interface_alt_setting(
- handle_, interface_number, alternate_setting);
- if (rv == LIBUSB_SUCCESS) {
- claimed_interfaces_[interface_number]->set_alternate_setting(
- alternate_setting);
- RefreshEndpointMap();
- } else {
- USB_LOG(EVENT) << "Failed to set interface " << interface_number
- << " to alternate setting " << alternate_setting << ": "
- << ConvertPlatformUsbErrorToString(rv);
+ if (!device_ || !ContainsKey(claimed_interfaces_, interface_number)) {
+ task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+ return;
}
- return rv == LIBUSB_SUCCESS;
-}
-
-bool UsbDeviceHandleImpl::ResetDevice() {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!device_)
- return false;
- const int rv = libusb_reset_device(handle_);
- if (rv != LIBUSB_SUCCESS) {
- USB_LOG(EVENT) << "Failed to reset device: "
- << ConvertPlatformUsbErrorToString(rv);
- }
- return rv == LIBUSB_SUCCESS;
+ blocking_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &UsbDeviceHandleImpl::SetInterfaceAlternateSettingOnBlockingThread,
+ this, handle_, interface_number, alternate_setting, callback));
}
-bool UsbDeviceHandleImpl::GetStringDescriptor(uint8 string_id,
- base::string16* string) {
- if (!GetSupportedLanguages()) {
- return false;
- }
-
- std::map<uint8, base::string16>::const_iterator it = strings_.find(string_id);
- if (it != strings_.end()) {
- *string = it->second;
- return true;
- }
-
- for (size_t i = 0; i < languages_.size(); ++i) {
- // Get the string using language ID.
- uint16 language_id = languages_[i];
- // The 1-byte length field limits the descriptor to 256-bytes (128 char16s).
- base::char16 text[128];
- int size =
- libusb_get_string_descriptor(handle_,
- string_id,
- language_id,
- reinterpret_cast<unsigned char*>(&text[0]),
- sizeof(text));
- if (size < 0) {
- USB_LOG(EVENT) << "Failed to get string descriptor " << string_id
- << " (langid " << language_id
- << "): " << ConvertPlatformUsbErrorToString(size);
- continue;
- } else if (size < 2) {
- USB_LOG(EVENT) << "String descriptor " << string_id << " (langid "
- << language_id << ") has no header.";
- continue;
- // The first 2 bytes of the descriptor are the total length and type tag.
- } else if ((text[0] & 0xff) != size) {
- USB_LOG(EVENT) << "String descriptor " << string_id << " (langid "
- << language_id << ") size mismatch: " << (text[0] & 0xff)
- << " != " << size;
- continue;
- } else if ((text[0] >> 8) != LIBUSB_DT_STRING) {
- USB_LOG(EVENT) << "String descriptor " << string_id << " (langid "
- << language_id << ") is not a string descriptor.";
- continue;
- }
-
- *string = base::string16(text + 1, (size - 2) / 2);
- strings_[string_id] = *string;
- return true;
+void UsbDeviceHandleImpl::ResetDevice(const UsbSuccessCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!device_) {
+ task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+ return;
}
- return false;
+ blocking_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ResetDeviceOnBlockingThread,
+ this, handle_, callback));
}
void UsbDeviceHandleImpl::ControlTransfer(UsbEndpointDirection direction,
@@ -668,6 +611,13 @@ void UsbDeviceHandleImpl::ControlTransfer(UsbEndpointDirection direction,
size_t length,
unsigned int timeout,
const UsbTransferCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!device_) {
+ callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
+ return;
+ }
+
if (length > UINT16_MAX) {
USB_LOG(USER) << "Transfer too long.";
callback.Run(USB_TRANSFER_ERROR, buffer, 0);
@@ -685,14 +635,15 @@ void UsbDeviceHandleImpl::ControlTransfer(UsbEndpointDirection direction,
length);
scoped_ptr<Transfer> transfer = Transfer::CreateControlTransfer(
- CreateRequestType(direction, request_type, recipient), request, value,
- index, static_cast<uint16>(length), resized_buffer, timeout, callback);
+ this, CreateRequestType(direction, request_type, recipient), request,
+ value, index, static_cast<uint16>(length), resized_buffer, timeout,
+ task_runner_, callback);
if (!transfer) {
callback.Run(USB_TRANSFER_ERROR, buffer, 0);
return;
}
- PostOrSubmitTransfer(transfer.Pass());
+ SubmitTransfer(transfer.Pass());
}
void UsbDeviceHandleImpl::BulkTransfer(const UsbEndpointDirection direction,
@@ -701,6 +652,13 @@ void UsbDeviceHandleImpl::BulkTransfer(const UsbEndpointDirection direction,
const size_t length,
const unsigned int timeout,
const UsbTransferCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!device_) {
+ callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
+ return;
+ }
+
if (length > INT_MAX) {
USB_LOG(USER) << "Transfer too long.";
callback.Run(USB_TRANSFER_ERROR, buffer, 0);
@@ -708,10 +666,10 @@ void UsbDeviceHandleImpl::BulkTransfer(const UsbEndpointDirection direction,
}
scoped_ptr<Transfer> transfer = Transfer::CreateBulkTransfer(
- ConvertTransferDirection(direction) | endpoint, buffer,
- static_cast<int>(length), timeout, callback);
+ this, ConvertTransferDirection(direction) | endpoint, buffer,
+ static_cast<int>(length), timeout, task_runner_, callback);
- PostOrSubmitTransfer(transfer.Pass());
+ SubmitTransfer(transfer.Pass());
}
void UsbDeviceHandleImpl::InterruptTransfer(
@@ -721,6 +679,13 @@ void UsbDeviceHandleImpl::InterruptTransfer(
size_t length,
unsigned int timeout,
const UsbTransferCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!device_) {
+ callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
+ return;
+ }
+
if (length > INT_MAX) {
USB_LOG(USER) << "Transfer too long.";
callback.Run(USB_TRANSFER_ERROR, buffer, 0);
@@ -728,10 +693,10 @@ void UsbDeviceHandleImpl::InterruptTransfer(
}
scoped_ptr<Transfer> transfer = Transfer::CreateInterruptTransfer(
- ConvertTransferDirection(direction) | endpoint, buffer,
- static_cast<int>(length), timeout, callback);
+ this, ConvertTransferDirection(direction) | endpoint, buffer,
+ static_cast<int>(length), timeout, task_runner_, callback);
- PostOrSubmitTransfer(transfer.Pass());
+ SubmitTransfer(transfer.Pass());
}
void UsbDeviceHandleImpl::IsochronousTransfer(
@@ -743,6 +708,13 @@ void UsbDeviceHandleImpl::IsochronousTransfer(
const unsigned int packet_length,
const unsigned int timeout,
const UsbTransferCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!device_) {
+ callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
+ return;
+ }
+
if (length > INT_MAX) {
USB_LOG(USER) << "Transfer too long.";
callback.Run(USB_TRANSFER_ERROR, buffer, 0);
@@ -750,10 +722,112 @@ void UsbDeviceHandleImpl::IsochronousTransfer(
}
scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer(
- ConvertTransferDirection(direction) | endpoint, buffer,
- static_cast<int>(length), packets, packet_length, timeout, callback);
+ this, ConvertTransferDirection(direction) | endpoint, buffer,
+ static_cast<int>(length), packets, packet_length, timeout, task_runner_,
+ callback);
+
+ SubmitTransfer(transfer.Pass());
+}
+
+void UsbDeviceHandleImpl::SetConfigurationOnBlockingThread(
+ PlatformUsbDeviceHandle handle,
+ int configuration_value,
+ const UsbSuccessCallback& callback) {
+ int rv = libusb_set_configuration(handle_, configuration_value);
+ if (rv != LIBUSB_SUCCESS) {
+ USB_LOG(EVENT) << "Failed to set configuration " << configuration_value
+ << ": " << ConvertPlatformUsbErrorToString(rv);
+ }
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&UsbDeviceHandleImpl::SetConfigurationComplete,
+ this, rv == LIBUSB_SUCCESS, callback));
+}
+
+void UsbDeviceHandleImpl::SetConfigurationComplete(
+ bool success,
+ const UsbSuccessCallback& callback) {
+ if (success) {
+ device_->RefreshConfiguration();
+ RefreshEndpointMap();
+ }
+ callback.Run(success);
+}
+
+void UsbDeviceHandleImpl::ClaimInterfaceOnBlockingThread(
+ PlatformUsbDeviceHandle handle,
+ int interface_number,
+ const UsbSuccessCallback& callback) {
+ int rv = libusb_claim_interface(handle, interface_number);
+ if (rv != LIBUSB_SUCCESS) {
+ VLOG(1) << "Failed to claim interface: "
+ << ConvertPlatformUsbErrorToString(rv);
+ }
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ClaimInterfaceComplete, this,
+ interface_number, rv == LIBUSB_SUCCESS, callback));
+}
+
+void UsbDeviceHandleImpl::ClaimInterfaceComplete(
+ int interface_number,
+ bool success,
+ const UsbSuccessCallback& callback) {
+ if (success) {
+ claimed_interfaces_[interface_number] =
+ new InterfaceClaimer(this, interface_number);
+ RefreshEndpointMap();
+ }
+ callback.Run(success);
+}
- PostOrSubmitTransfer(transfer.Pass());
+void UsbDeviceHandleImpl::SetInterfaceAlternateSettingOnBlockingThread(
+ PlatformUsbDeviceHandle handle,
+ int interface_number,
+ int alternate_setting,
+ const UsbSuccessCallback& callback) {
+ int rv = libusb_set_interface_alt_setting(handle, interface_number,
+ alternate_setting);
+ if (rv != LIBUSB_SUCCESS) {
+ USB_LOG(EVENT) << "Failed to set interface " << interface_number
+ << " to alternate setting " << alternate_setting << ": "
+ << ConvertPlatformUsbErrorToString(rv);
+ }
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&UsbDeviceHandleImpl::SetInterfaceAlternateSettingComplete,
+ this, interface_number, alternate_setting,
+ rv == LIBUSB_SUCCESS, callback));
+}
+
+void UsbDeviceHandleImpl::SetInterfaceAlternateSettingComplete(
+ int interface_number,
+ int alternate_setting,
+ bool success,
+ const UsbSuccessCallback& callback) {
+ if (success) {
+ claimed_interfaces_[interface_number]->set_alternate_setting(
+ alternate_setting);
+ RefreshEndpointMap();
+ }
+ callback.Run(success);
+}
+
+void UsbDeviceHandleImpl::ResetDeviceOnBlockingThread(
+ PlatformUsbDeviceHandle handle,
+ const UsbSuccessCallback& callback) {
+ int rv = libusb_reset_device(handle);
+ if (rv != LIBUSB_SUCCESS) {
+ USB_LOG(EVENT) << "Failed to reset device: "
+ << ConvertPlatformUsbErrorToString(rv);
+ }
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ResetDeviceComplete, this,
+ rv == LIBUSB_SUCCESS, callback));
+}
+
+void UsbDeviceHandleImpl::ResetDeviceComplete(
+ bool success,
+ const UsbSuccessCallback& callback) {
+ callback.Run(success);
}
void UsbDeviceHandleImpl::RefreshEndpointMap() {
@@ -785,69 +859,23 @@ UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(unsigned char endpoint) {
return NULL;
}
-void UsbDeviceHandleImpl::PostOrSubmitTransfer(scoped_ptr<Transfer> transfer) {
- if (task_runner_->RunsTasksOnCurrentThread()) {
- SubmitTransfer(transfer.Pass());
- } else {
- task_runner_->PostTask(
- FROM_HERE, base::Bind(&UsbDeviceHandleImpl::SubmitTransfer, this,
- base::Passed(&transfer)));
- }
-}
-
void UsbDeviceHandleImpl::SubmitTransfer(scoped_ptr<Transfer> transfer) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (device_) {
- if (transfer->Submit(weak_factory_.GetWeakPtr())) {
- // Transfer is now owned by libusb until its completion callback is run.
- // This object holds a weak reference.
- transfers_.insert(transfer.release());
- }
- } else {
- transfer->Complete(USB_TRANSFER_DISCONNECT, 0);
- }
+ // Transfer is owned by libusb until its completion callback is run. This
+ // object holds a weak reference.
+ transfers_.insert(transfer.get());
+ blocking_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&Transfer::Submit, base::Unretained(transfer.release())));
}
-void UsbDeviceHandleImpl::CompleteTransfer(scoped_ptr<Transfer> transfer) {
- DCHECK(ContainsKey(transfers_, transfer.get()))
- << "Missing transfer completed";
- transfers_.erase(transfer.get());
- transfer->ProcessCompletion();
-}
-
-bool UsbDeviceHandleImpl::GetSupportedLanguages() {
- if (!languages_.empty()) {
- return true;
- }
-
- // The 1-byte length field limits the descriptor to 256-bytes (128 uint16s).
- uint16 languages[128];
- int size = libusb_get_string_descriptor(
- handle_,
- 0,
- 0,
- reinterpret_cast<unsigned char*>(&languages[0]),
- sizeof(languages));
- if (size < 0) {
- USB_LOG(EVENT) << "Failed to get list of supported languages: "
- << ConvertPlatformUsbErrorToString(size);
- return false;
- } else if (size < 2) {
- USB_LOG(EVENT) << "String descriptor zero has no header.";
- return false;
- // The first 2 bytes of the descriptor are the total length and type tag.
- } else if ((languages[0] & 0xff) != size) {
- USB_LOG(EVENT) << "String descriptor zero size mismatch: "
- << (languages[0] & 0xff) << " != " << size;
- return false;
- } else if ((languages[0] >> 8) != LIBUSB_DT_STRING) {
- USB_LOG(EVENT) << "String descriptor zero is not a string descriptor.";
- return false;
- }
-
- languages_.assign(languages[1], languages[(size - 2) / 2]);
- return true;
+void UsbDeviceHandleImpl::TransferComplete(Transfer* transfer,
+ const base::Closure& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(ContainsKey(transfers_, transfer)) << "Missing transfer completed";
+ transfers_.erase(transfer);
+ callback.Run();
}
void UsbDeviceHandleImpl::InternalClose() {

Powered by Google App Engine
This is Rietveld 408576698