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

Side by Side 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 unified diff | Download patch
OLDNEW
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 "device/usb/usb_device_handle_impl.h" 5 #include "device/usb/usb_device_handle_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 << ConvertPlatformUsbErrorToString(rv); 150 << ConvertPlatformUsbErrorToString(rv);
151 } 151 }
152 return rv == LIBUSB_SUCCESS; 152 return rv == LIBUSB_SUCCESS;
153 } 153 }
154 154
155 // This inner class owns the underlying libusb_transfer and may outlast 155 // This inner class owns the underlying libusb_transfer and may outlast
156 // the UsbDeviceHandle that created it. 156 // the UsbDeviceHandle that created it.
157 class UsbDeviceHandleImpl::Transfer { 157 class UsbDeviceHandleImpl::Transfer {
158 public: 158 public:
159 static scoped_ptr<Transfer> CreateControlTransfer( 159 static scoped_ptr<Transfer> CreateControlTransfer(
160 scoped_refptr<UsbDeviceHandleImpl> device_handle,
160 uint8 type, 161 uint8 type,
161 uint8 request, 162 uint8 request,
162 uint16 value, 163 uint16 value,
163 uint16 index, 164 uint16 index,
164 uint16 length, 165 uint16 length,
165 scoped_refptr<net::IOBuffer> buffer, 166 scoped_refptr<net::IOBuffer> buffer,
166 unsigned int timeout, 167 unsigned int timeout,
168 scoped_refptr<base::SequencedTaskRunner> task_runner,
167 const UsbTransferCallback& callback); 169 const UsbTransferCallback& callback);
168 static scoped_ptr<Transfer> CreateBulkTransfer( 170 static scoped_ptr<Transfer> CreateBulkTransfer(
171 scoped_refptr<UsbDeviceHandleImpl> device_handle,
169 uint8 endpoint, 172 uint8 endpoint,
170 scoped_refptr<net::IOBuffer> buffer, 173 scoped_refptr<net::IOBuffer> buffer,
171 int length, 174 int length,
172 unsigned int timeout, 175 unsigned int timeout,
176 scoped_refptr<base::SequencedTaskRunner> task_runner,
173 const UsbTransferCallback& callback); 177 const UsbTransferCallback& callback);
174 static scoped_ptr<Transfer> CreateInterruptTransfer( 178 static scoped_ptr<Transfer> CreateInterruptTransfer(
179 scoped_refptr<UsbDeviceHandleImpl> device_handle,
175 uint8 endpoint, 180 uint8 endpoint,
176 scoped_refptr<net::IOBuffer> buffer, 181 scoped_refptr<net::IOBuffer> buffer,
177 int length, 182 int length,
178 unsigned int timeout, 183 unsigned int timeout,
184 scoped_refptr<base::SequencedTaskRunner> task_runner,
179 const UsbTransferCallback& callback); 185 const UsbTransferCallback& callback);
180 static scoped_ptr<Transfer> CreateIsochronousTransfer( 186 static scoped_ptr<Transfer> CreateIsochronousTransfer(
187 scoped_refptr<UsbDeviceHandleImpl> device_handle,
181 uint8 endpoint, 188 uint8 endpoint,
182 scoped_refptr<net::IOBuffer> buffer, 189 scoped_refptr<net::IOBuffer> buffer,
183 size_t length, 190 size_t length,
184 unsigned int packets, 191 unsigned int packets,
185 unsigned int packet_length, 192 unsigned int packet_length,
186 unsigned int timeout, 193 unsigned int timeout,
194 scoped_refptr<base::SequencedTaskRunner> task_runner,
187 const UsbTransferCallback& callback); 195 const UsbTransferCallback& callback);
188 196
189 ~Transfer(); 197 ~Transfer();
190 198
191 bool Submit(base::WeakPtr<UsbDeviceHandleImpl> device_handle); 199 void Submit();
192 void Cancel(); 200 void Cancel();
193 void ProcessCompletion(); 201 void ProcessCompletion();
194 void Complete(UsbTransferStatus status, size_t bytes_transferred); 202 void TransferComplete(UsbTransferStatus status, size_t bytes_transferred);
195 203
196 const UsbDeviceHandleImpl::InterfaceClaimer* claimed_interface() const { 204 const UsbDeviceHandleImpl::InterfaceClaimer* claimed_interface() const {
197 return claimed_interface_.get(); 205 return claimed_interface_.get();
198 } 206 }
199 207
200 private: 208 private:
201 Transfer(UsbTransferType transfer_type, 209 Transfer(scoped_refptr<UsbDeviceHandleImpl> device_handle,
210 scoped_refptr<InterfaceClaimer> claimed_interface,
211 UsbTransferType transfer_type,
202 scoped_refptr<net::IOBuffer> buffer, 212 scoped_refptr<net::IOBuffer> buffer,
203 size_t length, 213 size_t length,
214 scoped_refptr<base::SequencedTaskRunner> task_runner,
204 const UsbTransferCallback& callback); 215 const UsbTransferCallback& callback);
205 216
206 static void LIBUSB_CALL PlatformCallback(PlatformUsbTransferHandle handle); 217 static void LIBUSB_CALL PlatformCallback(PlatformUsbTransferHandle handle);
207 218
208 UsbTransferType transfer_type_; 219 UsbTransferType transfer_type_;
209 base::WeakPtr<UsbDeviceHandleImpl> device_handle_; 220 scoped_refptr<UsbDeviceHandleImpl> device_handle_;
210 PlatformUsbTransferHandle platform_transfer_; 221 PlatformUsbTransferHandle platform_transfer_;
211 scoped_refptr<net::IOBuffer> buffer_; 222 scoped_refptr<net::IOBuffer> buffer_;
212 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface_; 223 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface_;
213 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
214 size_t length_; 224 size_t length_;
215 bool cancelled_; 225 bool cancelled_;
226 scoped_refptr<base::SequencedTaskRunner> task_runner_;
216 UsbTransferCallback callback_; 227 UsbTransferCallback callback_;
217 scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner_;
218 }; 228 };
219 229
220 // static 230 // static
221 scoped_ptr<UsbDeviceHandleImpl::Transfer> 231 scoped_ptr<UsbDeviceHandleImpl::Transfer>
222 UsbDeviceHandleImpl::Transfer::CreateControlTransfer( 232 UsbDeviceHandleImpl::Transfer::CreateControlTransfer(
233 scoped_refptr<UsbDeviceHandleImpl> device_handle,
223 uint8 type, 234 uint8 type,
224 uint8 request, 235 uint8 request,
225 uint16 value, 236 uint16 value,
226 uint16 index, 237 uint16 index,
227 uint16 length, 238 uint16 length,
228 scoped_refptr<net::IOBuffer> buffer, 239 scoped_refptr<net::IOBuffer> buffer,
229 unsigned int timeout, 240 unsigned int timeout,
241 scoped_refptr<base::SequencedTaskRunner> task_runner,
230 const UsbTransferCallback& callback) { 242 const UsbTransferCallback& callback) {
231 scoped_ptr<Transfer> transfer(new Transfer(USB_TRANSFER_CONTROL, buffer, 243 scoped_ptr<Transfer> transfer(
232 length + LIBUSB_CONTROL_SETUP_SIZE, 244 new Transfer(device_handle, nullptr, USB_TRANSFER_CONTROL, buffer,
233 callback)); 245 length + LIBUSB_CONTROL_SETUP_SIZE, task_runner, callback));
234 246
235 transfer->platform_transfer_ = libusb_alloc_transfer(0); 247 transfer->platform_transfer_ = libusb_alloc_transfer(0);
236 if (!transfer->platform_transfer_) { 248 if (!transfer->platform_transfer_) {
237 USB_LOG(ERROR) << "Failed to allocate control transfer."; 249 USB_LOG(ERROR) << "Failed to allocate control transfer.";
238 return nullptr; 250 return nullptr;
239 } 251 }
240 252
241 libusb_fill_control_setup(reinterpret_cast<uint8*>(buffer->data()), type, 253 libusb_fill_control_setup(reinterpret_cast<uint8*>(buffer->data()), type,
242 request, value, index, length); 254 request, value, index, length);
243 libusb_fill_control_transfer(transfer->platform_transfer_, 255 libusb_fill_control_transfer(transfer->platform_transfer_,
244 nullptr, /* filled in by Submit() */ 256 device_handle->handle_,
245 reinterpret_cast<uint8*>(buffer->data()), 257 reinterpret_cast<uint8*>(buffer->data()),
246 &UsbDeviceHandleImpl::Transfer::PlatformCallback, 258 &UsbDeviceHandleImpl::Transfer::PlatformCallback,
247 transfer.get(), timeout); 259 transfer.get(), timeout);
248 260
249 return transfer.Pass(); 261 return transfer.Pass();
250 } 262 }
251 263
252 // static 264 // static
253 scoped_ptr<UsbDeviceHandleImpl::Transfer> 265 scoped_ptr<UsbDeviceHandleImpl::Transfer>
254 UsbDeviceHandleImpl::Transfer::CreateBulkTransfer( 266 UsbDeviceHandleImpl::Transfer::CreateBulkTransfer(
267 scoped_refptr<UsbDeviceHandleImpl> device_handle,
255 uint8 endpoint, 268 uint8 endpoint,
256 scoped_refptr<net::IOBuffer> buffer, 269 scoped_refptr<net::IOBuffer> buffer,
257 int length, 270 int length,
258 unsigned int timeout, 271 unsigned int timeout,
272 scoped_refptr<base::SequencedTaskRunner> task_runner,
259 const UsbTransferCallback& callback) { 273 const UsbTransferCallback& callback) {
260 scoped_ptr<Transfer> transfer( 274 scoped_ptr<Transfer> transfer(new Transfer(
261 new Transfer(USB_TRANSFER_BULK, buffer, length, callback)); 275 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint),
276 USB_TRANSFER_BULK, buffer, length, task_runner, callback));
262 277
263 transfer->platform_transfer_ = libusb_alloc_transfer(0); 278 transfer->platform_transfer_ = libusb_alloc_transfer(0);
264 if (!transfer->platform_transfer_) { 279 if (!transfer->platform_transfer_) {
265 USB_LOG(ERROR) << "Failed to allocate bulk transfer."; 280 USB_LOG(ERROR) << "Failed to allocate bulk transfer.";
266 return nullptr; 281 return nullptr;
267 } 282 }
268 283
269 libusb_fill_bulk_transfer(transfer->platform_transfer_, 284 libusb_fill_bulk_transfer(
270 nullptr, /* filled in by Submit() */ 285 transfer->platform_transfer_, device_handle->handle_, endpoint,
271 endpoint, reinterpret_cast<uint8*>(buffer->data()), 286 reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length),
272 static_cast<int>(length), 287 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(),
273 &UsbDeviceHandleImpl::Transfer::PlatformCallback, 288 timeout);
274 transfer.get(), timeout);
275 289
276 return transfer.Pass(); 290 return transfer.Pass();
277 } 291 }
278 292
279 // static 293 // static
280 scoped_ptr<UsbDeviceHandleImpl::Transfer> 294 scoped_ptr<UsbDeviceHandleImpl::Transfer>
281 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer( 295 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer(
296 scoped_refptr<UsbDeviceHandleImpl> device_handle,
282 uint8 endpoint, 297 uint8 endpoint,
283 scoped_refptr<net::IOBuffer> buffer, 298 scoped_refptr<net::IOBuffer> buffer,
284 int length, 299 int length,
285 unsigned int timeout, 300 unsigned int timeout,
301 scoped_refptr<base::SequencedTaskRunner> task_runner,
286 const UsbTransferCallback& callback) { 302 const UsbTransferCallback& callback) {
287 scoped_ptr<Transfer> transfer( 303 scoped_ptr<Transfer> transfer(new Transfer(
288 new Transfer(USB_TRANSFER_INTERRUPT, buffer, length, callback)); 304 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint),
305 USB_TRANSFER_INTERRUPT, buffer, length, task_runner, callback));
289 306
290 transfer->platform_transfer_ = libusb_alloc_transfer(0); 307 transfer->platform_transfer_ = libusb_alloc_transfer(0);
291 if (!transfer->platform_transfer_) { 308 if (!transfer->platform_transfer_) {
292 USB_LOG(ERROR) << "Failed to allocate interrupt transfer."; 309 USB_LOG(ERROR) << "Failed to allocate interrupt transfer.";
293 return nullptr; 310 return nullptr;
294 } 311 }
295 312
296 libusb_fill_interrupt_transfer( 313 libusb_fill_interrupt_transfer(
297 transfer->platform_transfer_, nullptr, /* filled in by Submit() */ 314 transfer->platform_transfer_, device_handle->handle_, endpoint,
298 endpoint, reinterpret_cast<uint8*>(buffer->data()), 315 reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length),
299 static_cast<int>(length),
300 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), 316 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(),
301 timeout); 317 timeout);
302 318
303 return transfer.Pass(); 319 return transfer.Pass();
304 } 320 }
305 321
306 // static 322 // static
307 scoped_ptr<UsbDeviceHandleImpl::Transfer> 323 scoped_ptr<UsbDeviceHandleImpl::Transfer>
308 UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer( 324 UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer(
325 scoped_refptr<UsbDeviceHandleImpl> device_handle,
309 uint8 endpoint, 326 uint8 endpoint,
310 scoped_refptr<net::IOBuffer> buffer, 327 scoped_refptr<net::IOBuffer> buffer,
311 size_t length, 328 size_t length,
312 unsigned int packets, 329 unsigned int packets,
313 unsigned int packet_length, 330 unsigned int packet_length,
314 unsigned int timeout, 331 unsigned int timeout,
332 scoped_refptr<base::SequencedTaskRunner> task_runner,
315 const UsbTransferCallback& callback) { 333 const UsbTransferCallback& callback) {
316 DCHECK(packets <= length && (packets * packet_length) <= length) 334 DCHECK(packets <= length && (packets * packet_length) <= length)
317 << "transfer length is too small"; 335 << "transfer length is too small";
318 336
319 scoped_ptr<Transfer> transfer( 337 scoped_ptr<Transfer> transfer(new Transfer(
320 new Transfer(USB_TRANSFER_ISOCHRONOUS, buffer, length, callback)); 338 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint),
339 USB_TRANSFER_ISOCHRONOUS, buffer, length, task_runner, callback));
321 340
322 transfer->platform_transfer_ = libusb_alloc_transfer(packets); 341 transfer->platform_transfer_ = libusb_alloc_transfer(packets);
323 if (!transfer->platform_transfer_) { 342 if (!transfer->platform_transfer_) {
324 USB_LOG(ERROR) << "Failed to allocate isochronous transfer."; 343 USB_LOG(ERROR) << "Failed to allocate isochronous transfer.";
325 return nullptr; 344 return nullptr;
326 } 345 }
327 346
328 libusb_fill_iso_transfer( 347 libusb_fill_iso_transfer(
329 transfer->platform_transfer_, nullptr, /* filled in by Submit() */ 348 transfer->platform_transfer_, device_handle->handle_, endpoint,
330 endpoint, reinterpret_cast<uint8*>(buffer->data()), 349 reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length),
331 static_cast<int>(length), packets, &Transfer::PlatformCallback, 350 packets, &Transfer::PlatformCallback, transfer.get(), timeout);
332 transfer.get(), timeout);
333 libusb_set_iso_packet_lengths(transfer->platform_transfer_, packet_length); 351 libusb_set_iso_packet_lengths(transfer->platform_transfer_, packet_length);
334 352
335 return transfer.Pass(); 353 return transfer.Pass();
336 } 354 }
337 355
338 UsbDeviceHandleImpl::Transfer::Transfer(UsbTransferType transfer_type, 356 UsbDeviceHandleImpl::Transfer::Transfer(
339 scoped_refptr<net::IOBuffer> buffer, 357 scoped_refptr<UsbDeviceHandleImpl> device_handle,
340 size_t length, 358 scoped_refptr<InterfaceClaimer> claimed_interface,
341 const UsbTransferCallback& callback) 359 UsbTransferType transfer_type,
360 scoped_refptr<net::IOBuffer> buffer,
361 size_t length,
362 scoped_refptr<base::SequencedTaskRunner> task_runner,
363 const UsbTransferCallback& callback)
342 : transfer_type_(transfer_type), 364 : transfer_type_(transfer_type),
365 device_handle_(device_handle),
366 platform_transfer_(NULL),
343 buffer_(buffer), 367 buffer_(buffer),
368 claimed_interface_(claimed_interface),
344 length_(length), 369 length_(length),
345 cancelled_(false), 370 cancelled_(false),
371 task_runner_(task_runner),
346 callback_(callback) { 372 callback_(callback) {
347 // Remember the thread from which this transfer was created so that |callback|
348 // can be dispatched there.
349 callback_task_runner_ = base::ThreadTaskRunnerHandle::Get();
350 } 373 }
351 374
352 UsbDeviceHandleImpl::Transfer::~Transfer() { 375 UsbDeviceHandleImpl::Transfer::~Transfer() {
353 if (platform_transfer_) { 376 if (platform_transfer_) {
354 libusb_free_transfer(platform_transfer_); 377 libusb_free_transfer(platform_transfer_);
355 } 378 }
356 } 379 }
357 380
358 bool UsbDeviceHandleImpl::Transfer::Submit( 381 void UsbDeviceHandleImpl::Transfer::Submit() {
359 base::WeakPtr<UsbDeviceHandleImpl> device_handle) {
360 device_handle_ = device_handle;
361 // Remember the thread from which this transfer was submitted so that it can
362 // be marked complete there.
363 task_runner_ = base::ThreadTaskRunnerHandle::Get();
364 // GetClaimedInterfaceForEndpoint may return nullptr. libusb_submit_transfer
365 // will fail if it requires an interface we didn't claim.
366 claimed_interface_ = device_handle->GetClaimedInterfaceForEndpoint(
367 platform_transfer_->endpoint);
368 platform_transfer_->dev_handle = device_handle_->handle_;
369
370 const int rv = libusb_submit_transfer(platform_transfer_); 382 const int rv = libusb_submit_transfer(platform_transfer_);
371 if (rv == LIBUSB_SUCCESS) { 383 if (rv != LIBUSB_SUCCESS) {
372 return true;
373 } else {
374 USB_LOG(EVENT) << "Failed to submit transfer: " 384 USB_LOG(EVENT) << "Failed to submit transfer: "
375 << ConvertPlatformUsbErrorToString(rv); 385 << ConvertPlatformUsbErrorToString(rv);
376 Complete(USB_TRANSFER_ERROR, 0); 386 TransferComplete(USB_TRANSFER_ERROR, 0);
377 return false;
378 } 387 }
379 } 388 }
380 389
381 void UsbDeviceHandleImpl::Transfer::Cancel() { 390 void UsbDeviceHandleImpl::Transfer::Cancel() {
382 if (!cancelled_) { 391 if (!cancelled_) {
383 libusb_cancel_transfer(platform_transfer_); 392 libusb_cancel_transfer(platform_transfer_);
384 claimed_interface_ = nullptr; 393 claimed_interface_ = nullptr;
385 } 394 }
386 cancelled_ = true; 395 cancelled_ = true;
387 } 396 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 455
447 case USB_TRANSFER_BULK: 456 case USB_TRANSFER_BULK:
448 case USB_TRANSFER_INTERRUPT: 457 case USB_TRANSFER_INTERRUPT:
449 break; 458 break;
450 459
451 default: 460 default:
452 NOTREACHED() << "Invalid usb transfer type"; 461 NOTREACHED() << "Invalid usb transfer type";
453 break; 462 break;
454 } 463 }
455 464
456 Complete(ConvertTransferStatus(platform_transfer_->status), actual_length); 465 TransferComplete(ConvertTransferStatus(platform_transfer_->status),
457 } 466 actual_length);
458
459 void UsbDeviceHandleImpl::Transfer::Complete(UsbTransferStatus status,
460 size_t bytes_transferred) {
461 if (callback_task_runner_->RunsTasksOnCurrentThread()) {
462 callback_.Run(status, buffer_, bytes_transferred);
463 } else {
464 callback_task_runner_->PostTask(
465 FROM_HERE, base::Bind(callback_, status, buffer_, bytes_transferred));
466 }
467 } 467 }
468 468
469 /* static */ 469 /* static */
470 void LIBUSB_CALL UsbDeviceHandleImpl::Transfer::PlatformCallback( 470 void LIBUSB_CALL UsbDeviceHandleImpl::Transfer::PlatformCallback(
471 PlatformUsbTransferHandle platform_transfer) { 471 PlatformUsbTransferHandle platform_transfer) {
472 scoped_ptr<Transfer> transfer( 472 Transfer* transfer =
473 reinterpret_cast<Transfer*>(platform_transfer->user_data)); 473 reinterpret_cast<Transfer*>(platform_transfer->user_data);
474 DCHECK(transfer->platform_transfer_ == platform_transfer); 474 DCHECK(transfer->platform_transfer_ == platform_transfer);
475 475 transfer->ProcessCompletion();
476 // Because device_handle_ is a weak pointer it is guaranteed that the callback
477 // will be discarded if the handle has been freed.
478 Transfer* tmp_transfer = transfer.get(); // base::Passed invalidates transfer
479 tmp_transfer->task_runner_->PostTask(
480 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::CompleteTransfer,
481 tmp_transfer->device_handle_,
482 base::Passed(&transfer)));
483 } 476 }
484 477
485 UsbDeviceHandleImpl::UsbDeviceHandleImpl(scoped_refptr<UsbContext> context, 478 void UsbDeviceHandleImpl::Transfer::TransferComplete(UsbTransferStatus status,
486 scoped_refptr<UsbDeviceImpl> device, 479 size_t bytes_transferred) {
487 PlatformUsbDeviceHandle handle) 480 task_runner_->PostTask(
481 FROM_HERE,
482 base::Bind(&UsbDeviceHandleImpl::TransferComplete, device_handle_,
483 base::Owned(this),
484 base::Bind(callback_, status, buffer_, bytes_transferred)));
485 }
486
487 UsbDeviceHandleImpl::UsbDeviceHandleImpl(
488 scoped_refptr<UsbContext> context,
489 scoped_refptr<UsbDeviceImpl> device,
490 PlatformUsbDeviceHandle handle,
491 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
488 : device_(device), 492 : device_(device),
489 handle_(handle), 493 handle_(handle),
490 context_(context), 494 context_(context),
491 task_runner_(base::ThreadTaskRunnerHandle::Get()), 495 task_runner_(base::ThreadTaskRunnerHandle::Get()),
492 weak_factory_(this) { 496 blocking_task_runner_(blocking_task_runner) {
493 DCHECK(handle) << "Cannot create device with NULL handle."; 497 DCHECK(handle) << "Cannot create device with NULL handle.";
494 } 498 }
495 499
496 UsbDeviceHandleImpl::~UsbDeviceHandleImpl() { 500 UsbDeviceHandleImpl::~UsbDeviceHandleImpl() {
497 DCHECK(thread_checker_.CalledOnValidThread()); 501 DCHECK(thread_checker_.CalledOnValidThread());
498 502
499 libusb_close(handle_); 503 libusb_close(handle_);
500 handle_ = NULL; 504 handle_ = NULL;
501 } 505 }
502 506
503 scoped_refptr<UsbDevice> UsbDeviceHandleImpl::GetDevice() const { 507 scoped_refptr<UsbDevice> UsbDeviceHandleImpl::GetDevice() const {
504 return device_; 508 return device_;
505 } 509 }
506 510
507 void UsbDeviceHandleImpl::Close() { 511 void UsbDeviceHandleImpl::Close() {
508 DCHECK(thread_checker_.CalledOnValidThread()); 512 DCHECK(thread_checker_.CalledOnValidThread());
509 if (device_) 513 if (device_)
510 device_->Close(this); 514 device_->Close(this);
511 } 515 }
512 516
513 bool UsbDeviceHandleImpl::SetConfiguration(int configuration_value) { 517 void UsbDeviceHandleImpl::SetConfiguration(int configuration_value,
518 const UsbSuccessCallback& callback) {
514 DCHECK(thread_checker_.CalledOnValidThread()); 519 DCHECK(thread_checker_.CalledOnValidThread());
515 if (!device_) { 520 if (!device_) {
516 return false; 521 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
522 return;
517 } 523 }
518 524
519 for (Transfer* transfer : transfers_) { 525 for (Transfer* transfer : transfers_) {
520 transfer->Cancel(); 526 transfer->Cancel();
521 } 527 }
522 claimed_interfaces_.clear(); 528 claimed_interfaces_.clear();
523 529
524 int rv = libusb_set_configuration(handle_, configuration_value); 530 blocking_task_runner_->PostTask(
525 if (rv == LIBUSB_SUCCESS) { 531 FROM_HERE,
526 device_->RefreshConfiguration(); 532 base::Bind(&UsbDeviceHandleImpl::SetConfigurationOnBlockingThread, this,
527 RefreshEndpointMap(); 533 handle_, configuration_value, callback));
528 } else {
529 USB_LOG(EVENT) << "Failed to set configuration " << configuration_value
530 << ": " << ConvertPlatformUsbErrorToString(rv);
531 }
532 return rv == LIBUSB_SUCCESS;
533 } 534 }
534 535
535 bool UsbDeviceHandleImpl::ClaimInterface(const int interface_number) { 536 void UsbDeviceHandleImpl::ClaimInterface(int interface_number,
537 const UsbSuccessCallback& callback) {
538 DCHECK(thread_checker_.CalledOnValidThread());
539 if (!device_) {
540 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
541 return;
542 }
543 if (ContainsKey(claimed_interfaces_, interface_number)) {
544 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
545 return;
546 }
547
548 blocking_task_runner_->PostTask(
549 FROM_HERE,
550 base::Bind(&UsbDeviceHandleImpl::ClaimInterfaceOnBlockingThread, this,
551 handle_, interface_number, callback));
552 }
553
554 bool UsbDeviceHandleImpl::ReleaseInterface(int interface_number) {
536 DCHECK(thread_checker_.CalledOnValidThread()); 555 DCHECK(thread_checker_.CalledOnValidThread());
537 if (!device_) 556 if (!device_)
538 return false; 557 return false;
539 if (ContainsKey(claimed_interfaces_, interface_number))
540 return true;
541
542 scoped_refptr<InterfaceClaimer> claimer =
543 new InterfaceClaimer(this, interface_number);
544
545 if (claimer->Claim()) {
546 claimed_interfaces_[interface_number] = claimer;
547 RefreshEndpointMap();
548 return true;
549 }
550 return false;
551 }
552
553 bool UsbDeviceHandleImpl::ReleaseInterface(const int interface_number) {
554 DCHECK(thread_checker_.CalledOnValidThread());
555 if (!device_)
556 return false;
557 if (!ContainsKey(claimed_interfaces_, interface_number)) 558 if (!ContainsKey(claimed_interfaces_, interface_number))
558 return false; 559 return false;
559 560
560 // Cancel all the transfers on that interface. 561 // Cancel all the transfers on that interface.
561 InterfaceClaimer* interface_claimer = 562 InterfaceClaimer* interface_claimer =
562 claimed_interfaces_[interface_number].get(); 563 claimed_interfaces_[interface_number].get();
563 for (Transfer* transfer : transfers_) { 564 for (Transfer* transfer : transfers_) {
564 if (transfer->claimed_interface() == interface_claimer) { 565 if (transfer->claimed_interface() == interface_claimer) {
565 transfer->Cancel(); 566 transfer->Cancel();
566 } 567 }
567 } 568 }
568 claimed_interfaces_.erase(interface_number); 569 claimed_interfaces_.erase(interface_number);
569 570
570 RefreshEndpointMap(); 571 RefreshEndpointMap();
571 return true; 572 return true;
572 } 573 }
573 574
574 bool UsbDeviceHandleImpl::SetInterfaceAlternateSetting( 575 void UsbDeviceHandleImpl::SetInterfaceAlternateSetting(
575 const int interface_number, 576 int interface_number,
576 const int alternate_setting) { 577 int alternate_setting,
578 const UsbSuccessCallback& callback) {
577 DCHECK(thread_checker_.CalledOnValidThread()); 579 DCHECK(thread_checker_.CalledOnValidThread());
578 if (!device_) 580 if (!device_ || !ContainsKey(claimed_interfaces_, interface_number)) {
579 return false; 581 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
580 if (!ContainsKey(claimed_interfaces_, interface_number)) 582 return;
581 return false;
582 const int rv = libusb_set_interface_alt_setting(
583 handle_, interface_number, alternate_setting);
584 if (rv == LIBUSB_SUCCESS) {
585 claimed_interfaces_[interface_number]->set_alternate_setting(
586 alternate_setting);
587 RefreshEndpointMap();
588 } else {
589 USB_LOG(EVENT) << "Failed to set interface " << interface_number
590 << " to alternate setting " << alternate_setting << ": "
591 << ConvertPlatformUsbErrorToString(rv);
592 } 583 }
593 return rv == LIBUSB_SUCCESS; 584
585 blocking_task_runner_->PostTask(
586 FROM_HERE,
587 base::Bind(
588 &UsbDeviceHandleImpl::SetInterfaceAlternateSettingOnBlockingThread,
589 this, handle_, interface_number, alternate_setting, callback));
594 } 590 }
595 591
596 bool UsbDeviceHandleImpl::ResetDevice() { 592 void UsbDeviceHandleImpl::ResetDevice(const UsbSuccessCallback& callback) {
597 DCHECK(thread_checker_.CalledOnValidThread()); 593 DCHECK(thread_checker_.CalledOnValidThread());
598 if (!device_) 594 if (!device_) {
599 return false; 595 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
600 596 return;
601 const int rv = libusb_reset_device(handle_);
602 if (rv != LIBUSB_SUCCESS) {
603 USB_LOG(EVENT) << "Failed to reset device: "
604 << ConvertPlatformUsbErrorToString(rv);
605 }
606 return rv == LIBUSB_SUCCESS;
607 }
608
609 bool UsbDeviceHandleImpl::GetStringDescriptor(uint8 string_id,
610 base::string16* string) {
611 if (!GetSupportedLanguages()) {
612 return false;
613 } 597 }
614 598
615 std::map<uint8, base::string16>::const_iterator it = strings_.find(string_id); 599 blocking_task_runner_->PostTask(
616 if (it != strings_.end()) { 600 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ResetDeviceOnBlockingThread,
617 *string = it->second; 601 this, handle_, callback));
618 return true;
619 }
620
621 for (size_t i = 0; i < languages_.size(); ++i) {
622 // Get the string using language ID.
623 uint16 language_id = languages_[i];
624 // The 1-byte length field limits the descriptor to 256-bytes (128 char16s).
625 base::char16 text[128];
626 int size =
627 libusb_get_string_descriptor(handle_,
628 string_id,
629 language_id,
630 reinterpret_cast<unsigned char*>(&text[0]),
631 sizeof(text));
632 if (size < 0) {
633 USB_LOG(EVENT) << "Failed to get string descriptor " << string_id
634 << " (langid " << language_id
635 << "): " << ConvertPlatformUsbErrorToString(size);
636 continue;
637 } else if (size < 2) {
638 USB_LOG(EVENT) << "String descriptor " << string_id << " (langid "
639 << language_id << ") has no header.";
640 continue;
641 // The first 2 bytes of the descriptor are the total length and type tag.
642 } else if ((text[0] & 0xff) != size) {
643 USB_LOG(EVENT) << "String descriptor " << string_id << " (langid "
644 << language_id << ") size mismatch: " << (text[0] & 0xff)
645 << " != " << size;
646 continue;
647 } else if ((text[0] >> 8) != LIBUSB_DT_STRING) {
648 USB_LOG(EVENT) << "String descriptor " << string_id << " (langid "
649 << language_id << ") is not a string descriptor.";
650 continue;
651 }
652
653 *string = base::string16(text + 1, (size - 2) / 2);
654 strings_[string_id] = *string;
655 return true;
656 }
657
658 return false;
659 } 602 }
660 603
661 void UsbDeviceHandleImpl::ControlTransfer(UsbEndpointDirection direction, 604 void UsbDeviceHandleImpl::ControlTransfer(UsbEndpointDirection direction,
662 TransferRequestType request_type, 605 TransferRequestType request_type,
663 TransferRecipient recipient, 606 TransferRecipient recipient,
664 uint8 request, 607 uint8 request,
665 uint16 value, 608 uint16 value,
666 uint16 index, 609 uint16 index,
667 net::IOBuffer* buffer, 610 net::IOBuffer* buffer,
668 size_t length, 611 size_t length,
669 unsigned int timeout, 612 unsigned int timeout,
670 const UsbTransferCallback& callback) { 613 const UsbTransferCallback& callback) {
614 DCHECK(thread_checker_.CalledOnValidThread());
615
616 if (!device_) {
617 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
618 return;
619 }
620
671 if (length > UINT16_MAX) { 621 if (length > UINT16_MAX) {
672 USB_LOG(USER) << "Transfer too long."; 622 USB_LOG(USER) << "Transfer too long.";
673 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 623 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
674 return; 624 return;
675 } 625 }
676 626
677 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length; 627 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length;
678 scoped_refptr<net::IOBuffer> resized_buffer( 628 scoped_refptr<net::IOBuffer> resized_buffer(
679 new net::IOBufferWithSize(static_cast<int>(resized_length))); 629 new net::IOBufferWithSize(static_cast<int>(resized_length)));
680 if (!resized_buffer.get()) { 630 if (!resized_buffer.get()) {
681 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 631 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
682 return; 632 return;
683 } 633 }
684 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), 634 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(),
685 length); 635 length);
686 636
687 scoped_ptr<Transfer> transfer = Transfer::CreateControlTransfer( 637 scoped_ptr<Transfer> transfer = Transfer::CreateControlTransfer(
688 CreateRequestType(direction, request_type, recipient), request, value, 638 this, CreateRequestType(direction, request_type, recipient), request,
689 index, static_cast<uint16>(length), resized_buffer, timeout, callback); 639 value, index, static_cast<uint16>(length), resized_buffer, timeout,
640 task_runner_, callback);
690 if (!transfer) { 641 if (!transfer) {
691 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 642 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
692 return; 643 return;
693 } 644 }
694 645
695 PostOrSubmitTransfer(transfer.Pass()); 646 SubmitTransfer(transfer.Pass());
696 } 647 }
697 648
698 void UsbDeviceHandleImpl::BulkTransfer(const UsbEndpointDirection direction, 649 void UsbDeviceHandleImpl::BulkTransfer(const UsbEndpointDirection direction,
699 const uint8 endpoint, 650 const uint8 endpoint,
700 net::IOBuffer* buffer, 651 net::IOBuffer* buffer,
701 const size_t length, 652 const size_t length,
702 const unsigned int timeout, 653 const unsigned int timeout,
703 const UsbTransferCallback& callback) { 654 const UsbTransferCallback& callback) {
655 DCHECK(thread_checker_.CalledOnValidThread());
656
657 if (!device_) {
658 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
659 return;
660 }
661
704 if (length > INT_MAX) { 662 if (length > INT_MAX) {
705 USB_LOG(USER) << "Transfer too long."; 663 USB_LOG(USER) << "Transfer too long.";
706 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 664 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
707 return; 665 return;
708 } 666 }
709 667
710 scoped_ptr<Transfer> transfer = Transfer::CreateBulkTransfer( 668 scoped_ptr<Transfer> transfer = Transfer::CreateBulkTransfer(
711 ConvertTransferDirection(direction) | endpoint, buffer, 669 this, ConvertTransferDirection(direction) | endpoint, buffer,
712 static_cast<int>(length), timeout, callback); 670 static_cast<int>(length), timeout, task_runner_, callback);
713 671
714 PostOrSubmitTransfer(transfer.Pass()); 672 SubmitTransfer(transfer.Pass());
715 } 673 }
716 674
717 void UsbDeviceHandleImpl::InterruptTransfer( 675 void UsbDeviceHandleImpl::InterruptTransfer(
718 UsbEndpointDirection direction, 676 UsbEndpointDirection direction,
719 uint8 endpoint, 677 uint8 endpoint,
720 net::IOBuffer* buffer, 678 net::IOBuffer* buffer,
721 size_t length, 679 size_t length,
722 unsigned int timeout, 680 unsigned int timeout,
723 const UsbTransferCallback& callback) { 681 const UsbTransferCallback& callback) {
682 DCHECK(thread_checker_.CalledOnValidThread());
683
684 if (!device_) {
685 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
686 return;
687 }
688
724 if (length > INT_MAX) { 689 if (length > INT_MAX) {
725 USB_LOG(USER) << "Transfer too long."; 690 USB_LOG(USER) << "Transfer too long.";
726 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 691 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
727 return; 692 return;
728 } 693 }
729 694
730 scoped_ptr<Transfer> transfer = Transfer::CreateInterruptTransfer( 695 scoped_ptr<Transfer> transfer = Transfer::CreateInterruptTransfer(
731 ConvertTransferDirection(direction) | endpoint, buffer, 696 this, ConvertTransferDirection(direction) | endpoint, buffer,
732 static_cast<int>(length), timeout, callback); 697 static_cast<int>(length), timeout, task_runner_, callback);
733 698
734 PostOrSubmitTransfer(transfer.Pass()); 699 SubmitTransfer(transfer.Pass());
735 } 700 }
736 701
737 void UsbDeviceHandleImpl::IsochronousTransfer( 702 void UsbDeviceHandleImpl::IsochronousTransfer(
738 const UsbEndpointDirection direction, 703 const UsbEndpointDirection direction,
739 const uint8 endpoint, 704 const uint8 endpoint,
740 net::IOBuffer* buffer, 705 net::IOBuffer* buffer,
741 const size_t length, 706 const size_t length,
742 const unsigned int packets, 707 const unsigned int packets,
743 const unsigned int packet_length, 708 const unsigned int packet_length,
744 const unsigned int timeout, 709 const unsigned int timeout,
745 const UsbTransferCallback& callback) { 710 const UsbTransferCallback& callback) {
711 DCHECK(thread_checker_.CalledOnValidThread());
712
713 if (!device_) {
714 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
715 return;
716 }
717
746 if (length > INT_MAX) { 718 if (length > INT_MAX) {
747 USB_LOG(USER) << "Transfer too long."; 719 USB_LOG(USER) << "Transfer too long.";
748 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 720 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
749 return; 721 return;
750 } 722 }
751 723
752 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( 724 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer(
753 ConvertTransferDirection(direction) | endpoint, buffer, 725 this, ConvertTransferDirection(direction) | endpoint, buffer,
754 static_cast<int>(length), packets, packet_length, timeout, callback); 726 static_cast<int>(length), packets, packet_length, timeout, task_runner_,
727 callback);
755 728
756 PostOrSubmitTransfer(transfer.Pass()); 729 SubmitTransfer(transfer.Pass());
730 }
731
732 void UsbDeviceHandleImpl::SetConfigurationOnBlockingThread(
733 PlatformUsbDeviceHandle handle,
734 int configuration_value,
735 const UsbSuccessCallback& callback) {
736 int rv = libusb_set_configuration(handle_, configuration_value);
737 if (rv != LIBUSB_SUCCESS) {
738 USB_LOG(EVENT) << "Failed to set configuration " << configuration_value
739 << ": " << ConvertPlatformUsbErrorToString(rv);
740 }
741 task_runner_->PostTask(
742 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::SetConfigurationComplete,
743 this, rv == LIBUSB_SUCCESS, callback));
744 }
745
746 void UsbDeviceHandleImpl::SetConfigurationComplete(
747 bool success,
748 const UsbSuccessCallback& callback) {
749 if (success) {
750 device_->RefreshConfiguration();
751 RefreshEndpointMap();
752 }
753 callback.Run(success);
754 }
755
756 void UsbDeviceHandleImpl::ClaimInterfaceOnBlockingThread(
757 PlatformUsbDeviceHandle handle,
758 int interface_number,
759 const UsbSuccessCallback& callback) {
760 int rv = libusb_claim_interface(handle, interface_number);
761 if (rv != LIBUSB_SUCCESS) {
762 VLOG(1) << "Failed to claim interface: "
763 << ConvertPlatformUsbErrorToString(rv);
764 }
765 task_runner_->PostTask(
766 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ClaimInterfaceComplete, this,
767 interface_number, rv == LIBUSB_SUCCESS, callback));
768 }
769
770 void UsbDeviceHandleImpl::ClaimInterfaceComplete(
771 int interface_number,
772 bool success,
773 const UsbSuccessCallback& callback) {
774 if (success) {
775 claimed_interfaces_[interface_number] =
776 new InterfaceClaimer(this, interface_number);
777 RefreshEndpointMap();
778 }
779 callback.Run(success);
780 }
781
782 void UsbDeviceHandleImpl::SetInterfaceAlternateSettingOnBlockingThread(
783 PlatformUsbDeviceHandle handle,
784 int interface_number,
785 int alternate_setting,
786 const UsbSuccessCallback& callback) {
787 int rv = libusb_set_interface_alt_setting(handle, interface_number,
788 alternate_setting);
789 if (rv != LIBUSB_SUCCESS) {
790 USB_LOG(EVENT) << "Failed to set interface " << interface_number
791 << " to alternate setting " << alternate_setting << ": "
792 << ConvertPlatformUsbErrorToString(rv);
793 }
794 task_runner_->PostTask(
795 FROM_HERE,
796 base::Bind(&UsbDeviceHandleImpl::SetInterfaceAlternateSettingComplete,
797 this, interface_number, alternate_setting,
798 rv == LIBUSB_SUCCESS, callback));
799 }
800
801 void UsbDeviceHandleImpl::SetInterfaceAlternateSettingComplete(
802 int interface_number,
803 int alternate_setting,
804 bool success,
805 const UsbSuccessCallback& callback) {
806 if (success) {
807 claimed_interfaces_[interface_number]->set_alternate_setting(
808 alternate_setting);
809 RefreshEndpointMap();
810 }
811 callback.Run(success);
812 }
813
814 void UsbDeviceHandleImpl::ResetDeviceOnBlockingThread(
815 PlatformUsbDeviceHandle handle,
816 const UsbSuccessCallback& callback) {
817 int rv = libusb_reset_device(handle);
818 if (rv != LIBUSB_SUCCESS) {
819 USB_LOG(EVENT) << "Failed to reset device: "
820 << ConvertPlatformUsbErrorToString(rv);
821 }
822 task_runner_->PostTask(
823 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ResetDeviceComplete, this,
824 rv == LIBUSB_SUCCESS, callback));
825 }
826
827 void UsbDeviceHandleImpl::ResetDeviceComplete(
828 bool success,
829 const UsbSuccessCallback& callback) {
830 callback.Run(success);
757 } 831 }
758 832
759 void UsbDeviceHandleImpl::RefreshEndpointMap() { 833 void UsbDeviceHandleImpl::RefreshEndpointMap() {
760 DCHECK(thread_checker_.CalledOnValidThread()); 834 DCHECK(thread_checker_.CalledOnValidThread());
761 endpoint_map_.clear(); 835 endpoint_map_.clear();
762 const UsbConfigDescriptor* config = device_->GetConfiguration(); 836 const UsbConfigDescriptor* config = device_->GetConfiguration();
763 if (config) { 837 if (config) {
764 for (const auto& map_entry : claimed_interfaces_) { 838 for (const auto& map_entry : claimed_interfaces_) {
765 int interface_number = map_entry.first; 839 int interface_number = map_entry.first;
766 const scoped_refptr<InterfaceClaimer>& claimed_iface = map_entry.second; 840 const scoped_refptr<InterfaceClaimer>& claimed_iface = map_entry.second;
(...skipping 11 matching lines...) Expand all
778 } 852 }
779 } 853 }
780 854
781 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> 855 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer>
782 UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(unsigned char endpoint) { 856 UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(unsigned char endpoint) {
783 if (ContainsKey(endpoint_map_, endpoint)) 857 if (ContainsKey(endpoint_map_, endpoint))
784 return claimed_interfaces_[endpoint_map_[endpoint]]; 858 return claimed_interfaces_[endpoint_map_[endpoint]];
785 return NULL; 859 return NULL;
786 } 860 }
787 861
788 void UsbDeviceHandleImpl::PostOrSubmitTransfer(scoped_ptr<Transfer> transfer) {
789 if (task_runner_->RunsTasksOnCurrentThread()) {
790 SubmitTransfer(transfer.Pass());
791 } else {
792 task_runner_->PostTask(
793 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::SubmitTransfer, this,
794 base::Passed(&transfer)));
795 }
796 }
797
798 void UsbDeviceHandleImpl::SubmitTransfer(scoped_ptr<Transfer> transfer) { 862 void UsbDeviceHandleImpl::SubmitTransfer(scoped_ptr<Transfer> transfer) {
799 DCHECK(thread_checker_.CalledOnValidThread()); 863 DCHECK(thread_checker_.CalledOnValidThread());
800 864
801 if (device_) { 865 // Transfer is owned by libusb until its completion callback is run. This
802 if (transfer->Submit(weak_factory_.GetWeakPtr())) { 866 // object holds a weak reference.
803 // Transfer is now owned by libusb until its completion callback is run. 867 transfers_.insert(transfer.get());
804 // This object holds a weak reference. 868 blocking_task_runner_->PostTask(
805 transfers_.insert(transfer.release()); 869 FROM_HERE,
806 } 870 base::Bind(&Transfer::Submit, base::Unretained(transfer.release())));
807 } else {
808 transfer->Complete(USB_TRANSFER_DISCONNECT, 0);
809 }
810 } 871 }
811 872
812 void UsbDeviceHandleImpl::CompleteTransfer(scoped_ptr<Transfer> transfer) { 873 void UsbDeviceHandleImpl::TransferComplete(Transfer* transfer,
813 DCHECK(ContainsKey(transfers_, transfer.get())) 874 const base::Closure& callback) {
814 << "Missing transfer completed"; 875 DCHECK(thread_checker_.CalledOnValidThread());
815 transfers_.erase(transfer.get()); 876 DCHECK(ContainsKey(transfers_, transfer)) << "Missing transfer completed";
816 transfer->ProcessCompletion(); 877 transfers_.erase(transfer);
817 } 878 callback.Run();
818
819 bool UsbDeviceHandleImpl::GetSupportedLanguages() {
820 if (!languages_.empty()) {
821 return true;
822 }
823
824 // The 1-byte length field limits the descriptor to 256-bytes (128 uint16s).
825 uint16 languages[128];
826 int size = libusb_get_string_descriptor(
827 handle_,
828 0,
829 0,
830 reinterpret_cast<unsigned char*>(&languages[0]),
831 sizeof(languages));
832 if (size < 0) {
833 USB_LOG(EVENT) << "Failed to get list of supported languages: "
834 << ConvertPlatformUsbErrorToString(size);
835 return false;
836 } else if (size < 2) {
837 USB_LOG(EVENT) << "String descriptor zero has no header.";
838 return false;
839 // The first 2 bytes of the descriptor are the total length and type tag.
840 } else if ((languages[0] & 0xff) != size) {
841 USB_LOG(EVENT) << "String descriptor zero size mismatch: "
842 << (languages[0] & 0xff) << " != " << size;
843 return false;
844 } else if ((languages[0] >> 8) != LIBUSB_DT_STRING) {
845 USB_LOG(EVENT) << "String descriptor zero is not a string descriptor.";
846 return false;
847 }
848
849 languages_.assign(languages[1], languages[(size - 2) / 2]);
850 return true;
851 } 879 }
852 880
853 void UsbDeviceHandleImpl::InternalClose() { 881 void UsbDeviceHandleImpl::InternalClose() {
854 DCHECK(thread_checker_.CalledOnValidThread()); 882 DCHECK(thread_checker_.CalledOnValidThread());
855 if (!device_) 883 if (!device_)
856 return; 884 return;
857 885
858 // Cancel all the transfers. 886 // Cancel all the transfers.
859 for (Transfer* transfer : transfers_) { 887 for (Transfer* transfer : transfers_) {
860 // The callback will be called some time later. 888 // The callback will be called some time later.
861 transfer->Cancel(); 889 transfer->Cancel();
862 } 890 }
863 891
864 // Attempt-release all the interfaces. 892 // Attempt-release all the interfaces.
865 // It will be retained until the transfer cancellation is finished. 893 // It will be retained until the transfer cancellation is finished.
866 claimed_interfaces_.clear(); 894 claimed_interfaces_.clear();
867 895
868 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to 896 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to
869 // finish. 897 // finish.
870 device_ = NULL; 898 device_ = NULL;
871 } 899 }
872 900
873 } // namespace device 901 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698