Chromium Code Reviews| 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) { |
| 896 DCHECK(sequence_checker_.CalledOnValidSequence()); | |
| 873 if (timeout > 0) { | 897 if (timeout > 0) { |
|
mcasas
2017/04/24 21:19:23
nit: (timeout is unsigned int).
if (timeout == 0)
Reilly Grant (use Gerrit)
2017/04/24 22:14:00
Done.
| |
| 874 transfer->timeout_closure.Reset( | 898 transfer->timeout_closure.Reset( |
| 875 base::Bind(&UsbDeviceHandleUsbfs::CancelTransfer, this, transfer, | 899 base::Bind(&UsbDeviceHandleUsbfs::OnTimeout, this, transfer)); |
| 876 UsbTransferStatus::TIMEOUT)); | |
| 877 task_runner_->PostDelayedTask(FROM_HERE, | 900 task_runner_->PostDelayedTask(FROM_HERE, |
| 878 transfer->timeout_closure.callback(), | 901 transfer->timeout_closure.callback(), |
| 879 base::TimeDelta::FromMilliseconds(timeout)); | 902 base::TimeDelta::FromMilliseconds(timeout)); |
| 880 } | 903 } |
| 881 } | 904 } |
| 882 | 905 |
| 906 void UsbDeviceHandleUsbfs::OnTimeout(Transfer* transfer) { | |
| 907 CancelTransfer(transfer, UsbTransferStatus::TIMEOUT); | |
| 908 } | |
| 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 |