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 |