| 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 136 |
| 137 class UsbDeviceHandleUsbfs::FileThreadHelper | 137 class UsbDeviceHandleUsbfs::FileThreadHelper |
| 138 : public base::MessagePumpLibevent::Watcher, | 138 : public base::MessagePumpLibevent::Watcher, |
| 139 public base::MessageLoop::DestructionObserver { | 139 public base::MessageLoop::DestructionObserver { |
| 140 public: | 140 public: |
| 141 FileThreadHelper(int fd, | 141 FileThreadHelper(int fd, |
| 142 scoped_refptr<UsbDeviceHandleUsbfs> device_handle, | 142 scoped_refptr<UsbDeviceHandleUsbfs> device_handle, |
| 143 scoped_refptr<base::SequencedTaskRunner> task_runner); | 143 scoped_refptr<base::SequencedTaskRunner> task_runner); |
| 144 ~FileThreadHelper() override; | 144 ~FileThreadHelper() override; |
| 145 | 145 |
| 146 static void Start(scoped_ptr<FileThreadHelper> self); | 146 static void Start(std::unique_ptr<FileThreadHelper> self); |
| 147 | 147 |
| 148 // base::MessagePumpLibevent::Watcher overrides. | 148 // base::MessagePumpLibevent::Watcher overrides. |
| 149 void OnFileCanReadWithoutBlocking(int fd) override; | 149 void OnFileCanReadWithoutBlocking(int fd) override; |
| 150 void OnFileCanWriteWithoutBlocking(int fd) override; | 150 void OnFileCanWriteWithoutBlocking(int fd) override; |
| 151 | 151 |
| 152 // base::MessageLoop::DestructionObserver overrides. | 152 // base::MessageLoop::DestructionObserver overrides. |
| 153 void WillDestroyCurrentMessageLoop() override; | 153 void WillDestroyCurrentMessageLoop() override; |
| 154 | 154 |
| 155 private: | 155 private: |
| 156 int fd_; | 156 int fd_; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 168 scoped_refptr<base::SequencedTaskRunner> task_runner) | 168 scoped_refptr<base::SequencedTaskRunner> task_runner) |
| 169 : fd_(fd), device_handle_(device_handle), task_runner_(task_runner) {} | 169 : fd_(fd), device_handle_(device_handle), task_runner_(task_runner) {} |
| 170 | 170 |
| 171 UsbDeviceHandleUsbfs::FileThreadHelper::~FileThreadHelper() { | 171 UsbDeviceHandleUsbfs::FileThreadHelper::~FileThreadHelper() { |
| 172 DCHECK(thread_checker_.CalledOnValidThread()); | 172 DCHECK(thread_checker_.CalledOnValidThread()); |
| 173 base::MessageLoop::current()->RemoveDestructionObserver(this); | 173 base::MessageLoop::current()->RemoveDestructionObserver(this); |
| 174 } | 174 } |
| 175 | 175 |
| 176 // static | 176 // static |
| 177 void UsbDeviceHandleUsbfs::FileThreadHelper::Start( | 177 void UsbDeviceHandleUsbfs::FileThreadHelper::Start( |
| 178 scoped_ptr<FileThreadHelper> self) { | 178 std::unique_ptr<FileThreadHelper> self) { |
| 179 base::ThreadRestrictions::AssertIOAllowed(); | 179 base::ThreadRestrictions::AssertIOAllowed(); |
| 180 self->thread_checker_.DetachFromThread(); | 180 self->thread_checker_.DetachFromThread(); |
| 181 | 181 |
| 182 // Linux indicates that URBs are available to reap by marking the file | 182 // Linux indicates that URBs are available to reap by marking the file |
| 183 // descriptor writable. | 183 // descriptor writable. |
| 184 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( | 184 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( |
| 185 self->fd_, true, base::MessageLoopForIO::WATCH_WRITE, | 185 self->fd_, true, base::MessageLoopForIO::WATCH_WRITE, |
| 186 &self->file_watcher_, self.get())) { | 186 &self->file_watcher_, self.get())) { |
| 187 USB_LOG(ERROR) << "Failed to start watching device file descriptor."; | 187 USB_LOG(ERROR) << "Failed to start watching device file descriptor."; |
| 188 } | 188 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | 288 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) |
| 289 : device_(device), | 289 : device_(device), |
| 290 fd_(std::move(fd)), | 290 fd_(std::move(fd)), |
| 291 blocking_task_runner_(blocking_task_runner) { | 291 blocking_task_runner_(blocking_task_runner) { |
| 292 DCHECK(device_); | 292 DCHECK(device_); |
| 293 DCHECK(fd_.is_valid()); | 293 DCHECK(fd_.is_valid()); |
| 294 DCHECK(blocking_task_runner_); | 294 DCHECK(blocking_task_runner_); |
| 295 | 295 |
| 296 task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 296 task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 297 | 297 |
| 298 scoped_ptr<FileThreadHelper> helper( | 298 std::unique_ptr<FileThreadHelper> helper( |
| 299 new FileThreadHelper(fd_.get(), this, task_runner_)); | 299 new FileThreadHelper(fd_.get(), this, task_runner_)); |
| 300 helper_ = helper.get(); | 300 helper_ = helper.get(); |
| 301 blocking_task_runner_->PostTask( | 301 blocking_task_runner_->PostTask( |
| 302 FROM_HERE, base::Bind(&FileThreadHelper::Start, base::Passed(&helper))); | 302 FROM_HERE, base::Bind(&FileThreadHelper::Start, base::Passed(&helper))); |
| 303 } | 303 } |
| 304 | 304 |
| 305 scoped_refptr<UsbDevice> UsbDeviceHandleUsbfs::GetDevice() const { | 305 scoped_refptr<UsbDevice> UsbDeviceHandleUsbfs::GetDevice() const { |
| 306 return device_; | 306 return device_; |
| 307 } | 307 } |
| 308 | 308 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 scoped_refptr<net::IOBuffer> buffer, | 408 scoped_refptr<net::IOBuffer> buffer, |
| 409 size_t length, | 409 size_t length, |
| 410 unsigned int timeout, | 410 unsigned int timeout, |
| 411 const TransferCallback& callback) { | 411 const TransferCallback& callback) { |
| 412 if (!device_) { | 412 if (!device_) { |
| 413 task_runner_->PostTask( | 413 task_runner_->PostTask( |
| 414 FROM_HERE, base::Bind(callback, USB_TRANSFER_DISCONNECT, nullptr, 0)); | 414 FROM_HERE, base::Bind(callback, USB_TRANSFER_DISCONNECT, nullptr, 0)); |
| 415 return; | 415 return; |
| 416 } | 416 } |
| 417 | 417 |
| 418 scoped_ptr<Transfer> transfer(new (0) Transfer(buffer, callback)); | 418 std::unique_ptr<Transfer> transfer(new (0) Transfer(buffer, callback)); |
| 419 transfer->control_transfer_buffer = | 419 transfer->control_transfer_buffer = |
| 420 BuildControlTransferBuffer(direction, request_type, recipient, request, | 420 BuildControlTransferBuffer(direction, request_type, recipient, request, |
| 421 value, index, buffer, length); | 421 value, index, buffer, length); |
| 422 transfer->urb.type = USBDEVFS_URB_TYPE_CONTROL; | 422 transfer->urb.type = USBDEVFS_URB_TYPE_CONTROL; |
| 423 transfer->urb.endpoint = 0; | 423 transfer->urb.endpoint = 0; |
| 424 transfer->urb.buffer = transfer->control_transfer_buffer->data(); | 424 transfer->urb.buffer = transfer->control_transfer_buffer->data(); |
| 425 transfer->urb.buffer_length = 8 + length; | 425 transfer->urb.buffer_length = 8 + length; |
| 426 | 426 |
| 427 // USBDEVFS_SUBMITURB appears to be non-blocking as completion is reported | 427 // USBDEVFS_SUBMITURB appears to be non-blocking as completion is reported |
| 428 // by USBDEVFS_REAPURBNDELAY. | 428 // by USBDEVFS_REAPURBNDELAY. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 ConvertEndpointDirection(direction) | endpoint_number; | 479 ConvertEndpointDirection(direction) | endpoint_number; |
| 480 auto it = endpoints_.find(endpoint_address); | 480 auto it = endpoints_.find(endpoint_address); |
| 481 if (it == endpoints_.end()) { | 481 if (it == endpoints_.end()) { |
| 482 USB_LOG(USER) << "Endpoint address " << static_cast<int>(endpoint_address) | 482 USB_LOG(USER) << "Endpoint address " << static_cast<int>(endpoint_address) |
| 483 << " is not part of a claimed interface."; | 483 << " is not part of a claimed interface."; |
| 484 task_runner_->PostTask( | 484 task_runner_->PostTask( |
| 485 FROM_HERE, base::Bind(callback, USB_TRANSFER_ERROR, nullptr, 0)); | 485 FROM_HERE, base::Bind(callback, USB_TRANSFER_ERROR, nullptr, 0)); |
| 486 return; | 486 return; |
| 487 } | 487 } |
| 488 | 488 |
| 489 scoped_ptr<Transfer> transfer(new (0) Transfer(buffer, callback)); | 489 std::unique_ptr<Transfer> transfer(new (0) Transfer(buffer, callback)); |
| 490 transfer->urb.endpoint = endpoint_address; | 490 transfer->urb.endpoint = endpoint_address; |
| 491 transfer->urb.buffer_length = length; | 491 transfer->urb.buffer_length = length; |
| 492 transfer->urb.type = ConvertTransferType(it->second.type); | 492 transfer->urb.type = ConvertTransferType(it->second.type); |
| 493 | 493 |
| 494 // USBDEVFS_SUBMITURB appears to be non-blocking as completion is reported | 494 // USBDEVFS_SUBMITURB appears to be non-blocking as completion is reported |
| 495 // by USBDEVFS_REAPURBNDELAY. This code assumes a recent kernel that can | 495 // by USBDEVFS_REAPURBNDELAY. This code assumes a recent kernel that can |
| 496 // accept arbitrarily large transfer requests, hopefully also using a scatter- | 496 // accept arbitrarily large transfer requests, hopefully also using a scatter- |
| 497 // gather list. | 497 // gather list. |
| 498 int rc = HANDLE_EINTR(ioctl(fd_.get(), USBDEVFS_SUBMITURB, &transfer->urb)); | 498 int rc = HANDLE_EINTR(ioctl(fd_.get(), USBDEVFS_SUBMITURB, &transfer->urb)); |
| 499 if (rc) { | 499 if (rc) { |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 } | 651 } |
| 652 | 652 |
| 653 auto it = endpoints_.find(endpoint_address); | 653 auto it = endpoints_.find(endpoint_address); |
| 654 if (it == endpoints_.end()) { | 654 if (it == endpoints_.end()) { |
| 655 USB_LOG(USER) << "Endpoint address " << static_cast<int>(endpoint_address) | 655 USB_LOG(USER) << "Endpoint address " << static_cast<int>(endpoint_address) |
| 656 << " is not part of a claimed interface."; | 656 << " is not part of a claimed interface."; |
| 657 ReportIsochronousError(packet_lengths, callback, USB_TRANSFER_ERROR); | 657 ReportIsochronousError(packet_lengths, callback, USB_TRANSFER_ERROR); |
| 658 return; | 658 return; |
| 659 } | 659 } |
| 660 | 660 |
| 661 scoped_ptr<Transfer> transfer(new (packet_lengths.size()) | 661 std::unique_ptr<Transfer> transfer(new (packet_lengths.size()) |
| 662 Transfer(buffer, callback)); | 662 Transfer(buffer, callback)); |
| 663 transfer->urb.type = USBDEVFS_URB_TYPE_ISO; | 663 transfer->urb.type = USBDEVFS_URB_TYPE_ISO; |
| 664 transfer->urb.endpoint = endpoint_address; | 664 transfer->urb.endpoint = endpoint_address; |
| 665 transfer->urb.buffer_length = total_length; | 665 transfer->urb.buffer_length = total_length; |
| 666 | 666 |
| 667 for (size_t i = 0; i < packet_lengths.size(); ++i) | 667 for (size_t i = 0; i < packet_lengths.size(); ++i) |
| 668 transfer->urb.iso_frame_desc[i].length = packet_lengths[i]; | 668 transfer->urb.iso_frame_desc[i].length = packet_lengths[i]; |
| 669 | 669 |
| 670 // USBDEVFS_SUBMITURB appears to be non-blocking as completion is reported | 670 // USBDEVFS_SUBMITURB appears to be non-blocking as completion is reported |
| 671 // by USBDEVFS_REAPURBNDELAY. This code assumes a recent kernel that can | 671 // by USBDEVFS_REAPURBNDELAY. This code assumes a recent kernel that can |
| 672 // accept arbitrarily large transfer requests, hopefully also using a scatter- | 672 // accept arbitrarily large transfer requests, hopefully also using a scatter- |
| 673 // gather list. | 673 // gather list. |
| 674 int rc = HANDLE_EINTR(ioctl(fd_.get(), USBDEVFS_SUBMITURB, &transfer->urb)); | 674 int rc = HANDLE_EINTR(ioctl(fd_.get(), USBDEVFS_SUBMITURB, &transfer->urb)); |
| 675 if (rc) { | 675 if (rc) { |
| 676 rc = logging::GetLastSystemErrorCode(); | 676 rc = logging::GetLastSystemErrorCode(); |
| 677 USB_PLOG(DEBUG) << "Failed to submit transfer"; | 677 USB_PLOG(DEBUG) << "Failed to submit transfer"; |
| 678 ReportIsochronousError(packet_lengths, callback, ConvertTransferResult(rc)); | 678 ReportIsochronousError(packet_lengths, callback, ConvertTransferResult(rc)); |
| 679 } else { | 679 } else { |
| 680 SetUpTimeoutCallback(transfer.get(), timeout); | 680 SetUpTimeoutCallback(transfer.get(), timeout); |
| 681 transfers_.push_back(std::move(transfer)); | 681 transfers_.push_back(std::move(transfer)); |
| 682 } | 682 } |
| 683 } | 683 } |
| 684 | 684 |
| 685 void UsbDeviceHandleUsbfs::ReapedUrbs(const std::vector<usbdevfs_urb*>& urbs) { | 685 void UsbDeviceHandleUsbfs::ReapedUrbs(const std::vector<usbdevfs_urb*>& urbs) { |
| 686 for (const auto& urb : urbs) { | 686 for (const auto& urb : urbs) { |
| 687 Transfer* this_transfer = static_cast<Transfer*>(urb->usercontext); | 687 Transfer* this_transfer = static_cast<Transfer*>(urb->usercontext); |
| 688 DCHECK_EQ(urb, &this_transfer->urb); | 688 DCHECK_EQ(urb, &this_transfer->urb); |
| 689 auto it = std::find_if( | 689 auto it = std::find_if( |
| 690 transfers_.begin(), transfers_.end(), | 690 transfers_.begin(), transfers_.end(), |
| 691 [this_transfer](const scoped_ptr<Transfer>& transfer) -> bool { | 691 [this_transfer](const std::unique_ptr<Transfer>& transfer) -> bool { |
| 692 return transfer.get() == this_transfer; | 692 return transfer.get() == this_transfer; |
| 693 }); | 693 }); |
| 694 DCHECK(it != transfers_.end()); | 694 DCHECK(it != transfers_.end()); |
| 695 scoped_ptr<Transfer> transfer = std::move(*it); | 695 std::unique_ptr<Transfer> transfer = std::move(*it); |
| 696 transfers_.erase(it); | 696 transfers_.erase(it); |
| 697 TransferComplete(std::move(transfer)); | 697 TransferComplete(std::move(transfer)); |
| 698 } | 698 } |
| 699 } | 699 } |
| 700 | 700 |
| 701 void UsbDeviceHandleUsbfs::TransferComplete(scoped_ptr<Transfer> transfer) { | 701 void UsbDeviceHandleUsbfs::TransferComplete( |
| 702 std::unique_ptr<Transfer> transfer) { |
| 702 if (transfer->cancelled) | 703 if (transfer->cancelled) |
| 703 return; | 704 return; |
| 704 | 705 |
| 705 // The transfer will soon be freed. Cancel the timeout callback so that the | 706 // The transfer will soon be freed. Cancel the timeout callback so that the |
| 706 // raw pointer it holds to |transfer| is not used. | 707 // raw pointer it holds to |transfer| is not used. |
| 707 transfer->timeout_closure.Cancel(); | 708 transfer->timeout_closure.Cancel(); |
| 708 | 709 |
| 709 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { | 710 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { |
| 710 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); | 711 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); |
| 711 for (size_t i = 0; i < packets.size(); ++i) { | 712 for (size_t i = 0; i < packets.size(); ++i) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 packets[i].transferred_length = 0; | 798 packets[i].transferred_length = 0; |
| 798 packets[i].status = status; | 799 packets[i].status = status; |
| 799 } | 800 } |
| 800 transfer->isoc_callback.Run(transfer->buffer, packets); | 801 transfer->isoc_callback.Run(transfer->buffer, packets); |
| 801 } else { | 802 } else { |
| 802 transfer->callback.Run(status, transfer->buffer, 0); | 803 transfer->callback.Run(status, transfer->buffer, 0); |
| 803 } | 804 } |
| 804 } | 805 } |
| 805 | 806 |
| 806 } // namespace device | 807 } // namespace device |
| OLD | NEW |