OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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_usbfs.h" | 5 #include "device/usb/usb_device_handle_usbfs.h" |
6 | 6 |
7 #if defined(OS_ANDROID) && __ANDROID_API__ < 21 | 7 #if defined(OS_ANDROID) && __ANDROID_API__ < 21 |
8 #include <linux/usb_ch9.h> | 8 #include <linux/usb_ch9.h> |
9 #else | 9 #else |
10 #include <linux/usb/ch9.h> | 10 #include <linux/usb/ch9.h> |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 DCHECK(fd.is_valid()); | 416 DCHECK(fd.is_valid()); |
417 DCHECK(blocking_task_runner_); | 417 DCHECK(blocking_task_runner_); |
418 | 418 |
419 helper_.reset(new FileThreadHelper(std::move(fd), this, task_runner_)); | 419 helper_.reset(new FileThreadHelper(std::move(fd), this, task_runner_)); |
420 blocking_task_runner_->PostTask( | 420 blocking_task_runner_->PostTask( |
421 FROM_HERE, | 421 FROM_HERE, |
422 base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get()))); | 422 base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get()))); |
423 } | 423 } |
424 | 424 |
425 scoped_refptr<UsbDevice> UsbDeviceHandleUsbfs::GetDevice() const { | 425 scoped_refptr<UsbDevice> UsbDeviceHandleUsbfs::GetDevice() const { |
| 426 DCHECK(sequence_checker_.CalledOnValidSequence()); |
426 return device_; | 427 return device_; |
427 } | 428 } |
428 | 429 |
429 void UsbDeviceHandleUsbfs::Close() { | 430 void UsbDeviceHandleUsbfs::Close() { |
| 431 DCHECK(sequence_checker_.CalledOnValidSequence()); |
430 if (!device_) | 432 if (!device_) |
431 return; // Already closed. | 433 return; // Already closed. |
432 | 434 |
| 435 // Cancelling transfers may run or destroy callbacks holding the last |
| 436 // reference to this object so hold a reference for the rest of this method. |
| 437 scoped_refptr<UsbDeviceHandleUsbfs> self(this); |
| 438 for (const auto& transfer : transfers_) |
| 439 CancelTransfer(transfer.get(), UsbTransferStatus::CANCELLED); |
| 440 |
433 // On the |task_runner_| thread check |device_| to see if the handle is | 441 // On the |task_runner_| thread check |device_| to see if the handle is |
434 // closed. On the |blocking_task_runner_| thread check |fd_.is_valid()| to | 442 // closed. On the |blocking_task_runner_| thread check |fd_.is_valid()| to |
435 // see if the handle is closed. | 443 // see if the handle is closed. |
436 device_->HandleClosed(this); | 444 device_->HandleClosed(this); |
437 device_ = nullptr; | 445 device_ = nullptr; |
438 | 446 |
439 for (const auto& transfer : transfers_) | |
440 CancelTransfer(transfer.get(), UsbTransferStatus::CANCELLED); | |
441 | |
442 // Releases |helper_|. | 447 // Releases |helper_|. |
443 blocking_task_runner_->PostTask( | 448 blocking_task_runner_->PostTask( |
444 FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::CloseBlocking, this)); | 449 FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::CloseBlocking, this)); |
445 } | 450 } |
446 | 451 |
447 void UsbDeviceHandleUsbfs::SetConfiguration(int configuration_value, | 452 void UsbDeviceHandleUsbfs::SetConfiguration(int configuration_value, |
448 const ResultCallback& callback) { | 453 const ResultCallback& callback) { |
| 454 DCHECK(sequence_checker_.CalledOnValidSequence()); |
449 if (!device_) { | 455 if (!device_) { |
450 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 456 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
451 return; | 457 return; |
452 } | 458 } |
453 | 459 |
454 // USBDEVFS_SETCONFIGURATION synchronously issues a SET_CONFIGURATION request | 460 // USBDEVFS_SETCONFIGURATION synchronously issues a SET_CONFIGURATION request |
455 // to the device so it must be performed on a thread where it is okay to | 461 // to the device so it must be performed on a thread where it is okay to |
456 // block. | 462 // block. |
457 blocking_task_runner_->PostTask( | 463 blocking_task_runner_->PostTask( |
458 FROM_HERE, | 464 FROM_HERE, |
459 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::SetConfiguration, | 465 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::SetConfiguration, |
460 base::Unretained(helper_.get()), configuration_value, | 466 base::Unretained(helper_.get()), configuration_value, |
461 callback)); | 467 callback)); |
462 } | 468 } |
463 | 469 |
464 void UsbDeviceHandleUsbfs::ClaimInterface(int interface_number, | 470 void UsbDeviceHandleUsbfs::ClaimInterface(int interface_number, |
465 const ResultCallback& callback) { | 471 const ResultCallback& callback) { |
| 472 DCHECK(sequence_checker_.CalledOnValidSequence()); |
466 if (!device_) { | 473 if (!device_) { |
467 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 474 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
468 return; | 475 return; |
469 } | 476 } |
470 | 477 |
471 if (base::ContainsKey(interfaces_, interface_number)) { | 478 if (base::ContainsKey(interfaces_, interface_number)) { |
472 USB_LOG(DEBUG) << "Interface " << interface_number << " already claimed."; | 479 USB_LOG(DEBUG) << "Interface " << interface_number << " already claimed."; |
473 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 480 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
474 return; | 481 return; |
475 } | 482 } |
476 | 483 |
477 // It appears safe to assume that this ioctl will not block. | 484 // It appears safe to assume that this ioctl will not block. |
478 int rc = HANDLE_EINTR(ioctl(fd_, USBDEVFS_CLAIMINTERFACE, &interface_number)); | 485 int rc = HANDLE_EINTR(ioctl(fd_, USBDEVFS_CLAIMINTERFACE, &interface_number)); |
479 if (rc) { | 486 if (rc) { |
480 USB_PLOG(DEBUG) << "Failed to claim interface " << interface_number; | 487 USB_PLOG(DEBUG) << "Failed to claim interface " << interface_number; |
481 } else { | 488 } else { |
482 interfaces_[interface_number].alternate_setting = 0; | 489 interfaces_[interface_number].alternate_setting = 0; |
483 RefreshEndpointInfo(); | 490 RefreshEndpointInfo(); |
484 } | 491 } |
485 task_runner_->PostTask(FROM_HERE, base::Bind(callback, rc == 0)); | 492 task_runner_->PostTask(FROM_HERE, base::Bind(callback, rc == 0)); |
486 } | 493 } |
487 | 494 |
488 void UsbDeviceHandleUsbfs::ReleaseInterface(int interface_number, | 495 void UsbDeviceHandleUsbfs::ReleaseInterface(int interface_number, |
489 const ResultCallback& callback) { | 496 const ResultCallback& callback) { |
| 497 DCHECK(sequence_checker_.CalledOnValidSequence()); |
490 if (!device_) { | 498 if (!device_) { |
491 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 499 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
492 return; | 500 return; |
493 } | 501 } |
494 | 502 |
495 // USBDEVFS_RELEASEINTERFACE may issue a SET_INTERFACE request to the | 503 // USBDEVFS_RELEASEINTERFACE may issue a SET_INTERFACE request to the |
496 // device to restore alternate setting 0 so it must be performed on a thread | 504 // device to restore alternate setting 0 so it must be performed on a thread |
497 // where it is okay to block. | 505 // where it is okay to block. |
498 blocking_task_runner_->PostTask( | 506 blocking_task_runner_->PostTask( |
499 FROM_HERE, | 507 FROM_HERE, |
500 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ReleaseInterface, | 508 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ReleaseInterface, |
501 base::Unretained(helper_.get()), interface_number, callback)); | 509 base::Unretained(helper_.get()), interface_number, callback)); |
502 } | 510 } |
503 | 511 |
504 void UsbDeviceHandleUsbfs::SetInterfaceAlternateSetting( | 512 void UsbDeviceHandleUsbfs::SetInterfaceAlternateSetting( |
505 int interface_number, | 513 int interface_number, |
506 int alternate_setting, | 514 int alternate_setting, |
507 const ResultCallback& callback) { | 515 const ResultCallback& callback) { |
| 516 DCHECK(sequence_checker_.CalledOnValidSequence()); |
508 if (!device_) { | 517 if (!device_) { |
509 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 518 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
510 return; | 519 return; |
511 } | 520 } |
512 | 521 |
513 // USBDEVFS_SETINTERFACE is synchronous because it issues a SET_INTERFACE | 522 // USBDEVFS_SETINTERFACE is synchronous because it issues a SET_INTERFACE |
514 // request to the device so it must be performed on a thread where it is okay | 523 // request to the device so it must be performed on a thread where it is okay |
515 // to block. | 524 // to block. |
516 blocking_task_runner_->PostTask( | 525 blocking_task_runner_->PostTask( |
517 FROM_HERE, | 526 FROM_HERE, |
518 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::SetInterface, | 527 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::SetInterface, |
519 base::Unretained(helper_.get()), interface_number, | 528 base::Unretained(helper_.get()), interface_number, |
520 alternate_setting, callback)); | 529 alternate_setting, callback)); |
521 } | 530 } |
522 | 531 |
523 void UsbDeviceHandleUsbfs::ResetDevice(const ResultCallback& callback) { | 532 void UsbDeviceHandleUsbfs::ResetDevice(const ResultCallback& callback) { |
| 533 DCHECK(sequence_checker_.CalledOnValidSequence()); |
524 if (!device_) { | 534 if (!device_) { |
525 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 535 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
526 return; | 536 return; |
527 } | 537 } |
528 | 538 |
529 // USBDEVFS_RESET is synchronous because it waits for the port to be reset | 539 // USBDEVFS_RESET is synchronous because it waits for the port to be reset |
530 // and the device re-enumerated so it must be performed on a thread where it | 540 // and the device re-enumerated so it must be performed on a thread where it |
531 // is okay to block. | 541 // is okay to block. |
532 blocking_task_runner_->PostTask( | 542 blocking_task_runner_->PostTask( |
533 FROM_HERE, | 543 FROM_HERE, |
534 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ResetDevice, | 544 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ResetDevice, |
535 base::Unretained(helper_.get()), callback)); | 545 base::Unretained(helper_.get()), callback)); |
536 } | 546 } |
537 | 547 |
538 void UsbDeviceHandleUsbfs::ClearHalt(uint8_t endpoint_address, | 548 void UsbDeviceHandleUsbfs::ClearHalt(uint8_t endpoint_address, |
539 const ResultCallback& callback) { | 549 const ResultCallback& callback) { |
| 550 DCHECK(sequence_checker_.CalledOnValidSequence()); |
540 if (!device_) { | 551 if (!device_) { |
541 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 552 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
542 return; | 553 return; |
543 } | 554 } |
544 | 555 |
545 // USBDEVFS_CLEAR_HALT is synchronous because it issues a CLEAR_FEATURE | 556 // USBDEVFS_CLEAR_HALT is synchronous because it issues a CLEAR_FEATURE |
546 // request to the device so it must be performed on a thread where it is okay | 557 // request to the device so it must be performed on a thread where it is okay |
547 // to block. | 558 // to block. |
548 blocking_task_runner_->PostTask( | 559 blocking_task_runner_->PostTask( |
549 FROM_HERE, | 560 FROM_HERE, |
550 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ClearHalt, | 561 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ClearHalt, |
551 base::Unretained(helper_.get()), endpoint_address, callback)); | 562 base::Unretained(helper_.get()), endpoint_address, callback)); |
552 } | 563 } |
553 | 564 |
554 void UsbDeviceHandleUsbfs::ControlTransfer( | 565 void UsbDeviceHandleUsbfs::ControlTransfer( |
555 UsbTransferDirection direction, | 566 UsbTransferDirection direction, |
556 UsbControlTransferType request_type, | 567 UsbControlTransferType request_type, |
557 UsbControlTransferRecipient recipient, | 568 UsbControlTransferRecipient recipient, |
558 uint8_t request, | 569 uint8_t request, |
559 uint16_t value, | 570 uint16_t value, |
560 uint16_t index, | 571 uint16_t index, |
561 scoped_refptr<net::IOBuffer> buffer, | 572 scoped_refptr<net::IOBuffer> buffer, |
562 size_t length, | 573 size_t length, |
563 unsigned int timeout, | 574 unsigned int timeout, |
564 const TransferCallback& callback) { | 575 const TransferCallback& callback) { |
| 576 DCHECK(sequence_checker_.CalledOnValidSequence()); |
565 if (!device_) { | 577 if (!device_) { |
566 task_runner_->PostTask( | 578 task_runner_->PostTask( |
567 FROM_HERE, | 579 FROM_HERE, |
568 base::Bind(callback, UsbTransferStatus::DISCONNECT, nullptr, 0)); | 580 base::Bind(callback, UsbTransferStatus::DISCONNECT, nullptr, 0)); |
569 return; | 581 return; |
570 } | 582 } |
571 | 583 |
572 std::unique_ptr<Transfer> transfer(new (0) | 584 std::unique_ptr<Transfer> transfer(new (0) |
573 Transfer(buffer, callback, nullptr)); | 585 Transfer(buffer, callback, nullptr)); |
574 transfer->control_transfer_buffer = | 586 transfer->control_transfer_buffer = |
(...skipping 16 matching lines...) Expand all Loading... |
591 SetUpTimeoutCallback(transfer.get(), timeout); | 603 SetUpTimeoutCallback(transfer.get(), timeout); |
592 transfers_.push_back(std::move(transfer)); | 604 transfers_.push_back(std::move(transfer)); |
593 } | 605 } |
594 } | 606 } |
595 | 607 |
596 void UsbDeviceHandleUsbfs::IsochronousTransferIn( | 608 void UsbDeviceHandleUsbfs::IsochronousTransferIn( |
597 uint8_t endpoint_number, | 609 uint8_t endpoint_number, |
598 const std::vector<uint32_t>& packet_lengths, | 610 const std::vector<uint32_t>& packet_lengths, |
599 unsigned int timeout, | 611 unsigned int timeout, |
600 const IsochronousTransferCallback& callback) { | 612 const IsochronousTransferCallback& callback) { |
| 613 DCHECK(sequence_checker_.CalledOnValidSequence()); |
601 uint8_t endpoint_address = USB_DIR_IN | endpoint_number; | 614 uint8_t endpoint_address = USB_DIR_IN | endpoint_number; |
602 size_t total_length = | 615 size_t total_length = |
603 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); | 616 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); |
604 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(total_length)); | 617 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(total_length)); |
605 IsochronousTransferInternal(endpoint_address, buffer, total_length, | 618 IsochronousTransferInternal(endpoint_address, buffer, total_length, |
606 packet_lengths, timeout, callback); | 619 packet_lengths, timeout, callback); |
607 } | 620 } |
608 | 621 |
609 void UsbDeviceHandleUsbfs::IsochronousTransferOut( | 622 void UsbDeviceHandleUsbfs::IsochronousTransferOut( |
610 uint8_t endpoint_number, | 623 uint8_t endpoint_number, |
611 scoped_refptr<net::IOBuffer> buffer, | 624 scoped_refptr<net::IOBuffer> buffer, |
612 const std::vector<uint32_t>& packet_lengths, | 625 const std::vector<uint32_t>& packet_lengths, |
613 unsigned int timeout, | 626 unsigned int timeout, |
614 const IsochronousTransferCallback& callback) { | 627 const IsochronousTransferCallback& callback) { |
| 628 DCHECK(sequence_checker_.CalledOnValidSequence()); |
615 uint8_t endpoint_address = USB_DIR_OUT | endpoint_number; | 629 uint8_t endpoint_address = USB_DIR_OUT | endpoint_number; |
616 size_t total_length = | 630 size_t total_length = |
617 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); | 631 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); |
618 IsochronousTransferInternal(endpoint_address, buffer, total_length, | 632 IsochronousTransferInternal(endpoint_address, buffer, total_length, |
619 packet_lengths, timeout, callback); | 633 packet_lengths, timeout, callback); |
620 } | 634 } |
621 | 635 |
622 void UsbDeviceHandleUsbfs::GenericTransfer(UsbTransferDirection direction, | 636 void UsbDeviceHandleUsbfs::GenericTransfer(UsbTransferDirection direction, |
623 uint8_t endpoint_number, | 637 uint8_t endpoint_number, |
624 scoped_refptr<net::IOBuffer> buffer, | 638 scoped_refptr<net::IOBuffer> buffer, |
625 size_t length, | 639 size_t length, |
626 unsigned int timeout, | 640 unsigned int timeout, |
627 const TransferCallback& callback) { | 641 const TransferCallback& callback) { |
628 if (task_runner_->BelongsToCurrentThread()) { | 642 if (task_runner_->BelongsToCurrentThread()) { |
629 GenericTransferInternal(direction, endpoint_number, buffer, length, timeout, | 643 GenericTransferInternal(direction, endpoint_number, buffer, length, timeout, |
630 callback, task_runner_); | 644 callback, task_runner_); |
631 } else { | 645 } else { |
632 task_runner_->PostTask( | 646 task_runner_->PostTask( |
633 FROM_HERE, | 647 FROM_HERE, |
634 base::Bind(&UsbDeviceHandleUsbfs::GenericTransferInternal, this, | 648 base::Bind(&UsbDeviceHandleUsbfs::GenericTransferInternal, this, |
635 direction, endpoint_number, buffer, length, timeout, | 649 direction, endpoint_number, buffer, length, timeout, |
636 callback, base::ThreadTaskRunnerHandle::Get())); | 650 callback, base::ThreadTaskRunnerHandle::Get())); |
637 } | 651 } |
638 } | 652 } |
639 | 653 |
640 const UsbInterfaceDescriptor* UsbDeviceHandleUsbfs::FindInterfaceByEndpoint( | 654 const UsbInterfaceDescriptor* UsbDeviceHandleUsbfs::FindInterfaceByEndpoint( |
641 uint8_t endpoint_address) { | 655 uint8_t endpoint_address) { |
| 656 DCHECK(sequence_checker_.CalledOnValidSequence()); |
642 auto it = endpoints_.find(endpoint_address); | 657 auto it = endpoints_.find(endpoint_address); |
643 if (it != endpoints_.end()) | 658 if (it != endpoints_.end()) |
644 return it->second.interface; | 659 return it->second.interface; |
645 return nullptr; | 660 return nullptr; |
646 } | 661 } |
647 | 662 |
648 UsbDeviceHandleUsbfs::~UsbDeviceHandleUsbfs() { | 663 UsbDeviceHandleUsbfs::~UsbDeviceHandleUsbfs() { |
649 DCHECK(!device_) << "Handle must be closed before it is destroyed."; | 664 DCHECK(!device_) << "Handle must be closed before it is destroyed."; |
650 } | 665 } |
651 | 666 |
652 void UsbDeviceHandleUsbfs::ReleaseFileDescriptor() { | 667 void UsbDeviceHandleUsbfs::ReleaseFileDescriptor() { |
653 // Calls to this method must be posted to |blocking_task_runner_|. | 668 // Calls to this method must be posted to |blocking_task_runner_|. |
654 helper_->ReleaseFileDescriptor(); | 669 helper_->ReleaseFileDescriptor(); |
655 helper_.reset(); | 670 helper_.reset(); |
656 } | 671 } |
657 | 672 |
658 void UsbDeviceHandleUsbfs::CloseBlocking() { | 673 void UsbDeviceHandleUsbfs::CloseBlocking() { |
659 // Calls to this method must be posted to |blocking_task_runner_|. | 674 // Calls to this method must be posted to |blocking_task_runner_|. |
660 helper_.reset(); | 675 helper_.reset(); |
661 } | 676 } |
662 | 677 |
663 void UsbDeviceHandleUsbfs::SetConfigurationComplete( | 678 void UsbDeviceHandleUsbfs::SetConfigurationComplete( |
664 int configuration_value, | 679 int configuration_value, |
665 bool success, | 680 bool success, |
666 const ResultCallback& callback) { | 681 const ResultCallback& callback) { |
| 682 DCHECK(sequence_checker_.CalledOnValidSequence()); |
667 if (success && device_) { | 683 if (success && device_) { |
668 device_->ActiveConfigurationChanged(configuration_value); | 684 device_->ActiveConfigurationChanged(configuration_value); |
669 // TODO(reillyg): If all interfaces are unclaimed before a new configuration | 685 // TODO(reillyg): If all interfaces are unclaimed before a new configuration |
670 // is set then this will do nothing. Investigate. | 686 // is set then this will do nothing. Investigate. |
671 RefreshEndpointInfo(); | 687 RefreshEndpointInfo(); |
672 } | 688 } |
673 callback.Run(success); | 689 callback.Run(success); |
674 } | 690 } |
675 | 691 |
676 void UsbDeviceHandleUsbfs::ReleaseInterfaceComplete( | 692 void UsbDeviceHandleUsbfs::ReleaseInterfaceComplete( |
677 int interface_number, | 693 int interface_number, |
678 const ResultCallback& callback) { | 694 const ResultCallback& callback) { |
| 695 DCHECK(sequence_checker_.CalledOnValidSequence()); |
679 auto it = interfaces_.find(interface_number); | 696 auto it = interfaces_.find(interface_number); |
680 DCHECK(it != interfaces_.end()); | 697 DCHECK(it != interfaces_.end()); |
681 interfaces_.erase(it); | 698 interfaces_.erase(it); |
682 RefreshEndpointInfo(); | 699 RefreshEndpointInfo(); |
683 callback.Run(true); | 700 callback.Run(true); |
684 } | 701 } |
685 | 702 |
686 void UsbDeviceHandleUsbfs::IsochronousTransferInternal( | 703 void UsbDeviceHandleUsbfs::IsochronousTransferInternal( |
687 uint8_t endpoint_address, | 704 uint8_t endpoint_address, |
688 scoped_refptr<net::IOBuffer> buffer, | 705 scoped_refptr<net::IOBuffer> buffer, |
689 size_t total_length, | 706 size_t total_length, |
690 const std::vector<uint32_t>& packet_lengths, | 707 const std::vector<uint32_t>& packet_lengths, |
691 unsigned int timeout, | 708 unsigned int timeout, |
692 const IsochronousTransferCallback& callback) { | 709 const IsochronousTransferCallback& callback) { |
| 710 DCHECK(sequence_checker_.CalledOnValidSequence()); |
693 if (!device_) { | 711 if (!device_) { |
694 ReportIsochronousError(packet_lengths, callback, | 712 ReportIsochronousError(packet_lengths, callback, |
695 UsbTransferStatus::DISCONNECT); | 713 UsbTransferStatus::DISCONNECT); |
696 return; | 714 return; |
697 } | 715 } |
698 | 716 |
699 auto it = endpoints_.find(endpoint_address); | 717 auto it = endpoints_.find(endpoint_address); |
700 if (it == endpoints_.end()) { | 718 if (it == endpoints_.end()) { |
701 USB_LOG(USER) << "Endpoint address " << static_cast<int>(endpoint_address) | 719 USB_LOG(USER) << "Endpoint address " << static_cast<int>(endpoint_address) |
702 << " is not part of a claimed interface."; | 720 << " is not part of a claimed interface."; |
(...skipping 27 matching lines...) Expand all Loading... |
730 } | 748 } |
731 | 749 |
732 void UsbDeviceHandleUsbfs::GenericTransferInternal( | 750 void UsbDeviceHandleUsbfs::GenericTransferInternal( |
733 UsbTransferDirection direction, | 751 UsbTransferDirection direction, |
734 uint8_t endpoint_number, | 752 uint8_t endpoint_number, |
735 scoped_refptr<net::IOBuffer> buffer, | 753 scoped_refptr<net::IOBuffer> buffer, |
736 size_t length, | 754 size_t length, |
737 unsigned int timeout, | 755 unsigned int timeout, |
738 const TransferCallback& callback, | 756 const TransferCallback& callback, |
739 scoped_refptr<base::SingleThreadTaskRunner> callback_runner) { | 757 scoped_refptr<base::SingleThreadTaskRunner> callback_runner) { |
| 758 DCHECK(sequence_checker_.CalledOnValidSequence()); |
740 if (!device_) { | 759 if (!device_) { |
741 callback_runner->PostTask( | 760 callback_runner->PostTask( |
742 FROM_HERE, | 761 FROM_HERE, |
743 base::Bind(callback, UsbTransferStatus::DISCONNECT, nullptr, 0)); | 762 base::Bind(callback, UsbTransferStatus::DISCONNECT, nullptr, 0)); |
744 return; | 763 return; |
745 } | 764 } |
746 | 765 |
747 uint8_t endpoint_address = | 766 uint8_t endpoint_address = |
748 ConvertEndpointDirection(direction) | endpoint_number; | 767 ConvertEndpointDirection(direction) | endpoint_number; |
749 auto it = endpoints_.find(endpoint_address); | 768 auto it = endpoints_.find(endpoint_address); |
(...skipping 22 matching lines...) Expand all Loading... |
772 USB_PLOG(DEBUG) << "Failed to submit transfer"; | 791 USB_PLOG(DEBUG) << "Failed to submit transfer"; |
773 callback_runner->PostTask( | 792 callback_runner->PostTask( |
774 FROM_HERE, base::Bind(callback, ConvertTransferResult(rc), nullptr, 0)); | 793 FROM_HERE, base::Bind(callback, ConvertTransferResult(rc), nullptr, 0)); |
775 } else { | 794 } else { |
776 SetUpTimeoutCallback(transfer.get(), timeout); | 795 SetUpTimeoutCallback(transfer.get(), timeout); |
777 transfers_.push_back(std::move(transfer)); | 796 transfers_.push_back(std::move(transfer)); |
778 } | 797 } |
779 } | 798 } |
780 | 799 |
781 void UsbDeviceHandleUsbfs::ReapedUrbs(const std::vector<usbdevfs_urb*>& urbs) { | 800 void UsbDeviceHandleUsbfs::ReapedUrbs(const std::vector<usbdevfs_urb*>& urbs) { |
| 801 DCHECK(sequence_checker_.CalledOnValidSequence()); |
782 for (auto* urb : urbs) { | 802 for (auto* urb : urbs) { |
783 Transfer* transfer = static_cast<Transfer*>(urb->usercontext); | 803 Transfer* transfer = static_cast<Transfer*>(urb->usercontext); |
784 DCHECK_EQ(urb, &transfer->urb); | 804 DCHECK_EQ(urb, &transfer->urb); |
785 | 805 |
786 if (transfer->cancelled) { | 806 if (transfer->cancelled) { |
787 transfer->reaped = true; | 807 transfer->reaped = true; |
788 if (transfer->discarded) | 808 if (transfer->discarded) |
789 RemoveFromTransferList(transfer); | 809 RemoveFromTransferList(transfer); |
790 } else { | 810 } else { |
791 TransferComplete(RemoveFromTransferList(transfer)); | 811 TransferComplete(RemoveFromTransferList(transfer)); |
792 } | 812 } |
793 } | 813 } |
794 } | 814 } |
795 | 815 |
796 void UsbDeviceHandleUsbfs::TransferComplete( | 816 void UsbDeviceHandleUsbfs::TransferComplete( |
797 std::unique_ptr<Transfer> transfer) { | 817 std::unique_ptr<Transfer> transfer) { |
| 818 DCHECK(sequence_checker_.CalledOnValidSequence()); |
798 if (transfer->cancelled) | 819 if (transfer->cancelled) |
799 return; | 820 return; |
800 | 821 |
801 // The transfer will soon be freed. Cancel the timeout callback so that the | 822 // The transfer will soon be freed. Cancel the timeout callback so that the |
802 // raw pointer it holds to |transfer| is not used. | 823 // raw pointer it holds to |transfer| is not used. |
803 transfer->timeout_closure.Cancel(); | 824 transfer->timeout_closure.Cancel(); |
804 | 825 |
805 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { | 826 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { |
806 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); | 827 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); |
807 for (size_t i = 0; i < packets.size(); ++i) { | 828 for (size_t i = 0; i < packets.size(); ++i) { |
(...skipping 14 matching lines...) Expand all Loading... |
822 transfer->control_transfer_buffer->data() + 8, | 843 transfer->control_transfer_buffer->data() + 8, |
823 transfer->urb.actual_length); | 844 transfer->urb.actual_length); |
824 } | 845 } |
825 | 846 |
826 transfer->RunCallback(ConvertTransferResult(-transfer->urb.status), | 847 transfer->RunCallback(ConvertTransferResult(-transfer->urb.status), |
827 transfer->urb.actual_length); | 848 transfer->urb.actual_length); |
828 } | 849 } |
829 } | 850 } |
830 | 851 |
831 void UsbDeviceHandleUsbfs::RefreshEndpointInfo() { | 852 void UsbDeviceHandleUsbfs::RefreshEndpointInfo() { |
| 853 DCHECK(sequence_checker_.CalledOnValidSequence()); |
832 endpoints_.clear(); | 854 endpoints_.clear(); |
833 | 855 |
834 const UsbConfigDescriptor* config = device_->active_configuration(); | 856 const UsbConfigDescriptor* config = device_->active_configuration(); |
835 if (!config) | 857 if (!config) |
836 return; | 858 return; |
837 | 859 |
838 for (const auto& entry : interfaces_) { | 860 for (const auto& entry : interfaces_) { |
839 auto interface_it = std::find_if( | 861 auto interface_it = std::find_if( |
840 config->interfaces.begin(), config->interfaces.end(), | 862 config->interfaces.begin(), config->interfaces.end(), |
841 [entry](const UsbInterfaceDescriptor& interface) { | 863 [entry](const UsbInterfaceDescriptor& interface) { |
842 uint8_t interface_number = entry.first; | 864 uint8_t interface_number = entry.first; |
843 uint8_t alternate_setting = entry.second.alternate_setting; | 865 uint8_t alternate_setting = entry.second.alternate_setting; |
844 return interface.interface_number == interface_number && | 866 return interface.interface_number == interface_number && |
845 interface.alternate_setting == alternate_setting; | 867 interface.alternate_setting == alternate_setting; |
846 }); | 868 }); |
847 DCHECK(interface_it != config->interfaces.end()); | 869 DCHECK(interface_it != config->interfaces.end()); |
848 | 870 |
849 for (const auto& endpoint : interface_it->endpoints) { | 871 for (const auto& endpoint : interface_it->endpoints) { |
850 EndpointInfo& info = endpoints_[endpoint.address]; | 872 EndpointInfo& info = endpoints_[endpoint.address]; |
851 info.type = endpoint.transfer_type; | 873 info.type = endpoint.transfer_type; |
852 info.interface = &*interface_it; | 874 info.interface = &*interface_it; |
853 } | 875 } |
854 } | 876 } |
855 } | 877 } |
856 | 878 |
857 void UsbDeviceHandleUsbfs::ReportIsochronousError( | 879 void UsbDeviceHandleUsbfs::ReportIsochronousError( |
858 const std::vector<uint32_t>& packet_lengths, | 880 const std::vector<uint32_t>& packet_lengths, |
859 const UsbDeviceHandle::IsochronousTransferCallback& callback, | 881 const UsbDeviceHandle::IsochronousTransferCallback& callback, |
860 UsbTransferStatus status) { | 882 UsbTransferStatus status) { |
| 883 DCHECK(sequence_checker_.CalledOnValidSequence()); |
861 std::vector<UsbDeviceHandle::IsochronousPacket> packets( | 884 std::vector<UsbDeviceHandle::IsochronousPacket> packets( |
862 packet_lengths.size()); | 885 packet_lengths.size()); |
863 for (size_t i = 0; i < packet_lengths.size(); ++i) { | 886 for (size_t i = 0; i < packet_lengths.size(); ++i) { |
864 packets[i].length = packet_lengths[i]; | 887 packets[i].length = packet_lengths[i]; |
865 packets[i].transferred_length = 0; | 888 packets[i].transferred_length = 0; |
866 packets[i].status = status; | 889 packets[i].status = status; |
867 } | 890 } |
868 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr, packets)); | 891 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr, packets)); |
869 } | 892 } |
870 | 893 |
871 void UsbDeviceHandleUsbfs::SetUpTimeoutCallback(Transfer* transfer, | 894 void UsbDeviceHandleUsbfs::SetUpTimeoutCallback(Transfer* transfer, |
872 unsigned int timeout) { | 895 unsigned int timeout) { |
873 if (timeout > 0) { | 896 DCHECK(sequence_checker_.CalledOnValidSequence()); |
874 transfer->timeout_closure.Reset( | 897 if (timeout == 0) |
875 base::Bind(&UsbDeviceHandleUsbfs::CancelTransfer, this, transfer, | 898 return; |
876 UsbTransferStatus::TIMEOUT)); | 899 |
877 task_runner_->PostDelayedTask(FROM_HERE, | 900 transfer->timeout_closure.Reset( |
878 transfer->timeout_closure.callback(), | 901 base::Bind(&UsbDeviceHandleUsbfs::OnTimeout, this, transfer)); |
879 base::TimeDelta::FromMilliseconds(timeout)); | 902 task_runner_->PostDelayedTask(FROM_HERE, transfer->timeout_closure.callback(), |
880 } | 903 base::TimeDelta::FromMilliseconds(timeout)); |
| 904 } |
| 905 |
| 906 void UsbDeviceHandleUsbfs::OnTimeout(Transfer* transfer) { |
| 907 CancelTransfer(transfer, UsbTransferStatus::TIMEOUT); |
881 } | 908 } |
882 | 909 |
883 std::unique_ptr<UsbDeviceHandleUsbfs::Transfer> | 910 std::unique_ptr<UsbDeviceHandleUsbfs::Transfer> |
884 UsbDeviceHandleUsbfs::RemoveFromTransferList(Transfer* transfer_ptr) { | 911 UsbDeviceHandleUsbfs::RemoveFromTransferList(Transfer* transfer_ptr) { |
| 912 DCHECK(sequence_checker_.CalledOnValidSequence()); |
885 auto it = std::find_if( | 913 auto it = std::find_if( |
886 transfers_.begin(), transfers_.end(), | 914 transfers_.begin(), transfers_.end(), |
887 [transfer_ptr](const std::unique_ptr<Transfer>& transfer) -> bool { | 915 [transfer_ptr](const std::unique_ptr<Transfer>& transfer) -> bool { |
888 return transfer.get() == transfer_ptr; | 916 return transfer.get() == transfer_ptr; |
889 }); | 917 }); |
890 DCHECK(it != transfers_.end()); | 918 DCHECK(it != transfers_.end()); |
891 std::unique_ptr<Transfer> transfer = std::move(*it); | 919 std::unique_ptr<Transfer> transfer = std::move(*it); |
892 transfers_.erase(it); | 920 transfers_.erase(it); |
893 return transfer; | 921 return transfer; |
894 } | 922 } |
895 | 923 |
896 void UsbDeviceHandleUsbfs::CancelTransfer(Transfer* transfer, | 924 void UsbDeviceHandleUsbfs::CancelTransfer(Transfer* transfer, |
897 UsbTransferStatus status) { | 925 UsbTransferStatus status) { |
| 926 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 927 DCHECK(device_); |
| 928 |
898 if (transfer->cancelled) | 929 if (transfer->cancelled) |
899 return; | 930 return; |
900 | 931 |
901 // |transfer| must stay in |transfers_| as it is still being processed by the | 932 // |transfer| must stay in |transfers_| as it is still being processed by the |
902 // kernel and will be reaped later. | 933 // kernel and will be reaped later. |
903 transfer->cancelled = true; | 934 transfer->cancelled = true; |
| 935 |
| 936 blocking_task_runner_->PostTask( |
| 937 FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::DiscardUrb, |
| 938 base::Unretained(helper_.get()), transfer)); |
| 939 |
| 940 // Cancelling |timeout_closure| and running completion callbacks may free |
| 941 // |this| so these operations must be performed at the end of this function. |
904 transfer->timeout_closure.Cancel(); | 942 transfer->timeout_closure.Cancel(); |
905 | 943 |
906 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { | 944 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { |
907 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); | 945 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); |
908 for (size_t i = 0; i < packets.size(); ++i) { | 946 for (size_t i = 0; i < packets.size(); ++i) { |
909 packets[i].length = transfer->urb.iso_frame_desc[i].length; | 947 packets[i].length = transfer->urb.iso_frame_desc[i].length; |
910 packets[i].transferred_length = 0; | 948 packets[i].transferred_length = 0; |
911 packets[i].status = status; | 949 packets[i].status = status; |
912 } | 950 } |
913 transfer->RunIsochronousCallback(packets); | 951 transfer->RunIsochronousCallback(packets); |
914 } else { | 952 } else { |
915 transfer->RunCallback(status, 0); | 953 transfer->RunCallback(status, 0); |
916 } | 954 } |
917 | |
918 blocking_task_runner_->PostTask( | |
919 FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::DiscardUrb, | |
920 base::Unretained(helper_.get()), transfer)); | |
921 } | 955 } |
922 | 956 |
923 | |
924 void UsbDeviceHandleUsbfs::UrbDiscarded(Transfer* transfer) { | 957 void UsbDeviceHandleUsbfs::UrbDiscarded(Transfer* transfer) { |
| 958 DCHECK(sequence_checker_.CalledOnValidSequence()); |
925 transfer->discarded = true; | 959 transfer->discarded = true; |
926 if (transfer->reaped) | 960 if (transfer->reaped) |
927 RemoveFromTransferList(transfer); | 961 RemoveFromTransferList(transfer); |
928 } | 962 } |
929 | 963 |
930 } // namespace device | 964 } // namespace device |
OLD | NEW |