OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "device/usb/usb_device_handle_impl.h" | 5 #include "device/usb/usb_device_handle_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> |
8 #include <numeric> | 9 #include <numeric> |
9 #include <utility> | 10 #include <utility> |
10 #include <vector> | 11 #include <vector> |
11 | 12 |
12 #include "base/bind.h" | 13 #include "base/bind.h" |
13 #include "base/location.h" | 14 #include "base/location.h" |
14 #include "base/macros.h" | 15 #include "base/macros.h" |
15 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
16 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
17 #include "base/strings/string16.h" | 18 #include "base/strings/string16.h" |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 if (!release_callback_.is_null()) { | 194 if (!release_callback_.is_null()) { |
194 task_runner_->PostTask(FROM_HERE, | 195 task_runner_->PostTask(FROM_HERE, |
195 base::Bind(release_callback_, rc == LIBUSB_SUCCESS)); | 196 base::Bind(release_callback_, rc == LIBUSB_SUCCESS)); |
196 } | 197 } |
197 } | 198 } |
198 | 199 |
199 // This inner class owns the underlying libusb_transfer and may outlast | 200 // This inner class owns the underlying libusb_transfer and may outlast |
200 // the UsbDeviceHandle that created it. | 201 // the UsbDeviceHandle that created it. |
201 class UsbDeviceHandleImpl::Transfer { | 202 class UsbDeviceHandleImpl::Transfer { |
202 public: | 203 public: |
203 static scoped_ptr<Transfer> CreateControlTransfer( | 204 static std::unique_ptr<Transfer> CreateControlTransfer( |
204 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 205 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
205 uint8_t type, | 206 uint8_t type, |
206 uint8_t request, | 207 uint8_t request, |
207 uint16_t value, | 208 uint16_t value, |
208 uint16_t index, | 209 uint16_t index, |
209 uint16_t length, | 210 uint16_t length, |
210 scoped_refptr<net::IOBuffer> buffer, | 211 scoped_refptr<net::IOBuffer> buffer, |
211 unsigned int timeout, | 212 unsigned int timeout, |
212 scoped_refptr<base::TaskRunner> callback_task_runner, | 213 scoped_refptr<base::TaskRunner> callback_task_runner, |
213 const TransferCallback& callback); | 214 const TransferCallback& callback); |
214 static scoped_ptr<Transfer> CreateBulkTransfer( | 215 static std::unique_ptr<Transfer> CreateBulkTransfer( |
215 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 216 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
216 uint8_t endpoint, | 217 uint8_t endpoint, |
217 scoped_refptr<net::IOBuffer> buffer, | 218 scoped_refptr<net::IOBuffer> buffer, |
218 int length, | 219 int length, |
219 unsigned int timeout, | 220 unsigned int timeout, |
220 scoped_refptr<base::TaskRunner> callback_task_runner, | 221 scoped_refptr<base::TaskRunner> callback_task_runner, |
221 const TransferCallback& callback); | 222 const TransferCallback& callback); |
222 static scoped_ptr<Transfer> CreateInterruptTransfer( | 223 static std::unique_ptr<Transfer> CreateInterruptTransfer( |
223 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 224 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
224 uint8_t endpoint, | 225 uint8_t endpoint, |
225 scoped_refptr<net::IOBuffer> buffer, | 226 scoped_refptr<net::IOBuffer> buffer, |
226 int length, | 227 int length, |
227 unsigned int timeout, | 228 unsigned int timeout, |
228 scoped_refptr<base::TaskRunner> callback_task_runner, | 229 scoped_refptr<base::TaskRunner> callback_task_runner, |
229 const TransferCallback& callback); | 230 const TransferCallback& callback); |
230 static scoped_ptr<Transfer> CreateIsochronousTransfer( | 231 static std::unique_ptr<Transfer> CreateIsochronousTransfer( |
231 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 232 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
232 uint8_t endpoint, | 233 uint8_t endpoint, |
233 scoped_refptr<net::IOBuffer> buffer, | 234 scoped_refptr<net::IOBuffer> buffer, |
234 size_t length, | 235 size_t length, |
235 const std::vector<uint32_t>& packet_lengths, | 236 const std::vector<uint32_t>& packet_lengths, |
236 unsigned int timeout, | 237 unsigned int timeout, |
237 scoped_refptr<base::TaskRunner> callback_task_runner, | 238 scoped_refptr<base::TaskRunner> callback_task_runner, |
238 const IsochronousTransferCallback& callback); | 239 const IsochronousTransferCallback& callback); |
239 | 240 |
240 ~Transfer(); | 241 ~Transfer(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface_; | 278 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface_; |
278 size_t length_; | 279 size_t length_; |
279 bool cancelled_ = false; | 280 bool cancelled_ = false; |
280 scoped_refptr<base::SequencedTaskRunner> task_runner_; | 281 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
281 scoped_refptr<base::TaskRunner> callback_task_runner_; | 282 scoped_refptr<base::TaskRunner> callback_task_runner_; |
282 TransferCallback callback_; | 283 TransferCallback callback_; |
283 IsochronousTransferCallback iso_callback_; | 284 IsochronousTransferCallback iso_callback_; |
284 }; | 285 }; |
285 | 286 |
286 // static | 287 // static |
287 scoped_ptr<UsbDeviceHandleImpl::Transfer> | 288 std::unique_ptr<UsbDeviceHandleImpl::Transfer> |
288 UsbDeviceHandleImpl::Transfer::CreateControlTransfer( | 289 UsbDeviceHandleImpl::Transfer::CreateControlTransfer( |
289 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 290 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
290 uint8_t type, | 291 uint8_t type, |
291 uint8_t request, | 292 uint8_t request, |
292 uint16_t value, | 293 uint16_t value, |
293 uint16_t index, | 294 uint16_t index, |
294 uint16_t length, | 295 uint16_t length, |
295 scoped_refptr<net::IOBuffer> buffer, | 296 scoped_refptr<net::IOBuffer> buffer, |
296 unsigned int timeout, | 297 unsigned int timeout, |
297 scoped_refptr<base::TaskRunner> callback_task_runner, | 298 scoped_refptr<base::TaskRunner> callback_task_runner, |
298 const TransferCallback& callback) { | 299 const TransferCallback& callback) { |
299 scoped_ptr<Transfer> transfer(new Transfer( | 300 std::unique_ptr<Transfer> transfer(new Transfer( |
300 device_handle, nullptr, USB_TRANSFER_CONTROL, buffer, | 301 device_handle, nullptr, USB_TRANSFER_CONTROL, buffer, |
301 length + LIBUSB_CONTROL_SETUP_SIZE, callback_task_runner, callback)); | 302 length + LIBUSB_CONTROL_SETUP_SIZE, callback_task_runner, callback)); |
302 | 303 |
303 transfer->platform_transfer_ = libusb_alloc_transfer(0); | 304 transfer->platform_transfer_ = libusb_alloc_transfer(0); |
304 if (!transfer->platform_transfer_) { | 305 if (!transfer->platform_transfer_) { |
305 USB_LOG(ERROR) << "Failed to allocate control transfer."; | 306 USB_LOG(ERROR) << "Failed to allocate control transfer."; |
306 return nullptr; | 307 return nullptr; |
307 } | 308 } |
308 | 309 |
309 libusb_fill_control_setup(reinterpret_cast<uint8_t*>(buffer->data()), type, | 310 libusb_fill_control_setup(reinterpret_cast<uint8_t*>(buffer->data()), type, |
310 request, value, index, length); | 311 request, value, index, length); |
311 libusb_fill_control_transfer(transfer->platform_transfer_, | 312 libusb_fill_control_transfer(transfer->platform_transfer_, |
312 device_handle->handle_, | 313 device_handle->handle_, |
313 reinterpret_cast<uint8_t*>(buffer->data()), | 314 reinterpret_cast<uint8_t*>(buffer->data()), |
314 &UsbDeviceHandleImpl::Transfer::PlatformCallback, | 315 &UsbDeviceHandleImpl::Transfer::PlatformCallback, |
315 transfer.get(), timeout); | 316 transfer.get(), timeout); |
316 | 317 |
317 return transfer; | 318 return transfer; |
318 } | 319 } |
319 | 320 |
320 // static | 321 // static |
321 scoped_ptr<UsbDeviceHandleImpl::Transfer> | 322 std::unique_ptr<UsbDeviceHandleImpl::Transfer> |
322 UsbDeviceHandleImpl::Transfer::CreateBulkTransfer( | 323 UsbDeviceHandleImpl::Transfer::CreateBulkTransfer( |
323 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 324 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
324 uint8_t endpoint, | 325 uint8_t endpoint, |
325 scoped_refptr<net::IOBuffer> buffer, | 326 scoped_refptr<net::IOBuffer> buffer, |
326 int length, | 327 int length, |
327 unsigned int timeout, | 328 unsigned int timeout, |
328 scoped_refptr<base::TaskRunner> callback_task_runner, | 329 scoped_refptr<base::TaskRunner> callback_task_runner, |
329 const TransferCallback& callback) { | 330 const TransferCallback& callback) { |
330 scoped_ptr<Transfer> transfer(new Transfer( | 331 std::unique_ptr<Transfer> transfer(new Transfer( |
331 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), | 332 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), |
332 USB_TRANSFER_BULK, buffer, length, callback_task_runner, callback)); | 333 USB_TRANSFER_BULK, buffer, length, callback_task_runner, callback)); |
333 | 334 |
334 transfer->platform_transfer_ = libusb_alloc_transfer(0); | 335 transfer->platform_transfer_ = libusb_alloc_transfer(0); |
335 if (!transfer->platform_transfer_) { | 336 if (!transfer->platform_transfer_) { |
336 USB_LOG(ERROR) << "Failed to allocate bulk transfer."; | 337 USB_LOG(ERROR) << "Failed to allocate bulk transfer."; |
337 return nullptr; | 338 return nullptr; |
338 } | 339 } |
339 | 340 |
340 libusb_fill_bulk_transfer(transfer->platform_transfer_, | 341 libusb_fill_bulk_transfer(transfer->platform_transfer_, |
341 device_handle->handle_, endpoint, | 342 device_handle->handle_, endpoint, |
342 reinterpret_cast<uint8_t*>(buffer->data()), length, | 343 reinterpret_cast<uint8_t*>(buffer->data()), length, |
343 &UsbDeviceHandleImpl::Transfer::PlatformCallback, | 344 &UsbDeviceHandleImpl::Transfer::PlatformCallback, |
344 transfer.get(), timeout); | 345 transfer.get(), timeout); |
345 | 346 |
346 return transfer; | 347 return transfer; |
347 } | 348 } |
348 | 349 |
349 // static | 350 // static |
350 scoped_ptr<UsbDeviceHandleImpl::Transfer> | 351 std::unique_ptr<UsbDeviceHandleImpl::Transfer> |
351 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer( | 352 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer( |
352 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 353 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
353 uint8_t endpoint, | 354 uint8_t endpoint, |
354 scoped_refptr<net::IOBuffer> buffer, | 355 scoped_refptr<net::IOBuffer> buffer, |
355 int length, | 356 int length, |
356 unsigned int timeout, | 357 unsigned int timeout, |
357 scoped_refptr<base::TaskRunner> callback_task_runner, | 358 scoped_refptr<base::TaskRunner> callback_task_runner, |
358 const TransferCallback& callback) { | 359 const TransferCallback& callback) { |
359 scoped_ptr<Transfer> transfer(new Transfer( | 360 std::unique_ptr<Transfer> transfer(new Transfer( |
360 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), | 361 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), |
361 USB_TRANSFER_INTERRUPT, buffer, length, callback_task_runner, callback)); | 362 USB_TRANSFER_INTERRUPT, buffer, length, callback_task_runner, callback)); |
362 | 363 |
363 transfer->platform_transfer_ = libusb_alloc_transfer(0); | 364 transfer->platform_transfer_ = libusb_alloc_transfer(0); |
364 if (!transfer->platform_transfer_) { | 365 if (!transfer->platform_transfer_) { |
365 USB_LOG(ERROR) << "Failed to allocate interrupt transfer."; | 366 USB_LOG(ERROR) << "Failed to allocate interrupt transfer."; |
366 return nullptr; | 367 return nullptr; |
367 } | 368 } |
368 | 369 |
369 libusb_fill_interrupt_transfer( | 370 libusb_fill_interrupt_transfer( |
370 transfer->platform_transfer_, device_handle->handle_, endpoint, | 371 transfer->platform_transfer_, device_handle->handle_, endpoint, |
371 reinterpret_cast<uint8_t*>(buffer->data()), length, | 372 reinterpret_cast<uint8_t*>(buffer->data()), length, |
372 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), | 373 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), |
373 timeout); | 374 timeout); |
374 | 375 |
375 return transfer; | 376 return transfer; |
376 } | 377 } |
377 | 378 |
378 // static | 379 // static |
379 scoped_ptr<UsbDeviceHandleImpl::Transfer> | 380 std::unique_ptr<UsbDeviceHandleImpl::Transfer> |
380 UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer( | 381 UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer( |
381 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 382 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
382 uint8_t endpoint, | 383 uint8_t endpoint, |
383 scoped_refptr<net::IOBuffer> buffer, | 384 scoped_refptr<net::IOBuffer> buffer, |
384 size_t length, | 385 size_t length, |
385 const std::vector<uint32_t>& packet_lengths, | 386 const std::vector<uint32_t>& packet_lengths, |
386 unsigned int timeout, | 387 unsigned int timeout, |
387 scoped_refptr<base::TaskRunner> callback_task_runner, | 388 scoped_refptr<base::TaskRunner> callback_task_runner, |
388 const IsochronousTransferCallback& callback) { | 389 const IsochronousTransferCallback& callback) { |
389 scoped_ptr<Transfer> transfer(new Transfer( | 390 std::unique_ptr<Transfer> transfer(new Transfer( |
390 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), | 391 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), |
391 buffer, callback_task_runner, callback)); | 392 buffer, callback_task_runner, callback)); |
392 | 393 |
393 int num_packets = static_cast<int>(packet_lengths.size()); | 394 int num_packets = static_cast<int>(packet_lengths.size()); |
394 transfer->platform_transfer_ = libusb_alloc_transfer(num_packets); | 395 transfer->platform_transfer_ = libusb_alloc_transfer(num_packets); |
395 if (!transfer->platform_transfer_) { | 396 if (!transfer->platform_transfer_) { |
396 USB_LOG(ERROR) << "Failed to allocate isochronous transfer."; | 397 USB_LOG(ERROR) << "Failed to allocate isochronous transfer."; |
397 return nullptr; | 398 return nullptr; |
398 } | 399 } |
399 | 400 |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 scoped_refptr<net::IOBuffer> resized_buffer = | 978 scoped_refptr<net::IOBuffer> resized_buffer = |
978 new net::IOBufferWithSize(resized_length); | 979 new net::IOBufferWithSize(resized_length); |
979 if (!resized_buffer.get()) { | 980 if (!resized_buffer.get()) { |
980 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 981 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, |
981 buffer, 0); | 982 buffer, 0); |
982 return; | 983 return; |
983 } | 984 } |
984 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), | 985 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), |
985 length); | 986 length); |
986 | 987 |
987 scoped_ptr<Transfer> transfer = Transfer::CreateControlTransfer( | 988 std::unique_ptr<Transfer> transfer = Transfer::CreateControlTransfer( |
988 this, CreateRequestType(direction, request_type, recipient), request, | 989 this, CreateRequestType(direction, request_type, recipient), request, |
989 value, index, static_cast<uint16_t>(length), resized_buffer, timeout, | 990 value, index, static_cast<uint16_t>(length), resized_buffer, timeout, |
990 callback_task_runner, callback); | 991 callback_task_runner, callback); |
991 if (!transfer) { | 992 if (!transfer) { |
992 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 993 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, |
993 buffer, 0); | 994 buffer, 0); |
994 return; | 995 return; |
995 } | 996 } |
996 | 997 |
997 SubmitTransfer(std::move(transfer)); | 998 SubmitTransfer(std::move(transfer)); |
998 } | 999 } |
999 | 1000 |
1000 void UsbDeviceHandleImpl::IsochronousTransferInInternal( | 1001 void UsbDeviceHandleImpl::IsochronousTransferInInternal( |
1001 uint8_t endpoint_address, | 1002 uint8_t endpoint_address, |
1002 const std::vector<uint32_t>& packet_lengths, | 1003 const std::vector<uint32_t>& packet_lengths, |
1003 unsigned int timeout, | 1004 unsigned int timeout, |
1004 scoped_refptr<base::TaskRunner> callback_task_runner, | 1005 scoped_refptr<base::TaskRunner> callback_task_runner, |
1005 const IsochronousTransferCallback& callback) { | 1006 const IsochronousTransferCallback& callback) { |
1006 DCHECK(thread_checker_.CalledOnValidThread()); | 1007 DCHECK(thread_checker_.CalledOnValidThread()); |
1007 | 1008 |
1008 if (!device_) { | 1009 if (!device_) { |
1009 ReportIsochronousTransferError(callback_task_runner, callback, | 1010 ReportIsochronousTransferError(callback_task_runner, callback, |
1010 packet_lengths, USB_TRANSFER_DISCONNECT); | 1011 packet_lengths, USB_TRANSFER_DISCONNECT); |
1011 return; | 1012 return; |
1012 } | 1013 } |
1013 | 1014 |
1014 size_t length = | 1015 size_t length = |
1015 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); | 1016 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); |
1016 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(length)); | 1017 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(length)); |
1017 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( | 1018 std::unique_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( |
1018 this, endpoint_address, buffer, length, packet_lengths, timeout, | 1019 this, endpoint_address, buffer, length, packet_lengths, timeout, |
1019 callback_task_runner, callback); | 1020 callback_task_runner, callback); |
1020 | 1021 |
1021 SubmitTransfer(std::move(transfer)); | 1022 SubmitTransfer(std::move(transfer)); |
1022 } | 1023 } |
1023 | 1024 |
1024 void UsbDeviceHandleImpl::IsochronousTransferOutInternal( | 1025 void UsbDeviceHandleImpl::IsochronousTransferOutInternal( |
1025 uint8_t endpoint_address, | 1026 uint8_t endpoint_address, |
1026 scoped_refptr<net::IOBuffer> buffer, | 1027 scoped_refptr<net::IOBuffer> buffer, |
1027 const std::vector<uint32_t>& packet_lengths, | 1028 const std::vector<uint32_t>& packet_lengths, |
1028 unsigned int timeout, | 1029 unsigned int timeout, |
1029 scoped_refptr<base::TaskRunner> callback_task_runner, | 1030 scoped_refptr<base::TaskRunner> callback_task_runner, |
1030 const IsochronousTransferCallback& callback) { | 1031 const IsochronousTransferCallback& callback) { |
1031 DCHECK(thread_checker_.CalledOnValidThread()); | 1032 DCHECK(thread_checker_.CalledOnValidThread()); |
1032 | 1033 |
1033 if (!device_) { | 1034 if (!device_) { |
1034 ReportIsochronousTransferError(callback_task_runner, callback, | 1035 ReportIsochronousTransferError(callback_task_runner, callback, |
1035 packet_lengths, USB_TRANSFER_DISCONNECT); | 1036 packet_lengths, USB_TRANSFER_DISCONNECT); |
1036 return; | 1037 return; |
1037 } | 1038 } |
1038 | 1039 |
1039 size_t length = | 1040 size_t length = |
1040 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); | 1041 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); |
1041 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( | 1042 std::unique_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( |
1042 this, endpoint_address, buffer, length, packet_lengths, timeout, | 1043 this, endpoint_address, buffer, length, packet_lengths, timeout, |
1043 callback_task_runner, callback); | 1044 callback_task_runner, callback); |
1044 | 1045 |
1045 SubmitTransfer(std::move(transfer)); | 1046 SubmitTransfer(std::move(transfer)); |
1046 } | 1047 } |
1047 | 1048 |
1048 void UsbDeviceHandleImpl::GenericTransferInternal( | 1049 void UsbDeviceHandleImpl::GenericTransferInternal( |
1049 uint8_t endpoint_address, | 1050 uint8_t endpoint_address, |
1050 scoped_refptr<net::IOBuffer> buffer, | 1051 scoped_refptr<net::IOBuffer> buffer, |
1051 size_t length, | 1052 size_t length, |
(...skipping 18 matching lines...) Expand all Loading... |
1070 return; | 1071 return; |
1071 } | 1072 } |
1072 | 1073 |
1073 if (!base::IsValueInRangeForNumericType<int>(length)) { | 1074 if (!base::IsValueInRangeForNumericType<int>(length)) { |
1074 USB_LOG(DEBUG) << "Transfer too long."; | 1075 USB_LOG(DEBUG) << "Transfer too long."; |
1075 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 1076 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, |
1076 buffer, 0); | 1077 buffer, 0); |
1077 return; | 1078 return; |
1078 } | 1079 } |
1079 | 1080 |
1080 scoped_ptr<Transfer> transfer; | 1081 std::unique_ptr<Transfer> transfer; |
1081 UsbTransferType transfer_type = endpoint_it->second.endpoint->transfer_type; | 1082 UsbTransferType transfer_type = endpoint_it->second.endpoint->transfer_type; |
1082 if (transfer_type == USB_TRANSFER_BULK) { | 1083 if (transfer_type == USB_TRANSFER_BULK) { |
1083 transfer = Transfer::CreateBulkTransfer(this, endpoint_address, buffer, | 1084 transfer = Transfer::CreateBulkTransfer(this, endpoint_address, buffer, |
1084 static_cast<int>(length), timeout, | 1085 static_cast<int>(length), timeout, |
1085 callback_task_runner, callback); | 1086 callback_task_runner, callback); |
1086 } else if (transfer_type == USB_TRANSFER_INTERRUPT) { | 1087 } else if (transfer_type == USB_TRANSFER_INTERRUPT) { |
1087 transfer = Transfer::CreateInterruptTransfer( | 1088 transfer = Transfer::CreateInterruptTransfer( |
1088 this, endpoint_address, buffer, static_cast<int>(length), timeout, | 1089 this, endpoint_address, buffer, static_cast<int>(length), timeout, |
1089 callback_task_runner, callback); | 1090 callback_task_runner, callback); |
1090 } else { | 1091 } else { |
1091 USB_LOG(DEBUG) << "Endpoint " << static_cast<int>(endpoint_address) | 1092 USB_LOG(DEBUG) << "Endpoint " << static_cast<int>(endpoint_address) |
1092 << " is not a bulk or interrupt endpoint."; | 1093 << " is not a bulk or interrupt endpoint."; |
1093 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 1094 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, |
1094 buffer, 0); | 1095 buffer, 0); |
1095 return; | 1096 return; |
1096 } | 1097 } |
1097 | 1098 |
1098 SubmitTransfer(std::move(transfer)); | 1099 SubmitTransfer(std::move(transfer)); |
1099 } | 1100 } |
1100 | 1101 |
1101 void UsbDeviceHandleImpl::SubmitTransfer(scoped_ptr<Transfer> transfer) { | 1102 void UsbDeviceHandleImpl::SubmitTransfer(std::unique_ptr<Transfer> transfer) { |
1102 DCHECK(thread_checker_.CalledOnValidThread()); | 1103 DCHECK(thread_checker_.CalledOnValidThread()); |
1103 | 1104 |
1104 // Transfer is owned by libusb until its completion callback is run. This | 1105 // Transfer is owned by libusb until its completion callback is run. This |
1105 // object holds a weak reference. | 1106 // object holds a weak reference. |
1106 transfers_.insert(transfer.get()); | 1107 transfers_.insert(transfer.get()); |
1107 blocking_task_runner_->PostTask( | 1108 blocking_task_runner_->PostTask( |
1108 FROM_HERE, | 1109 FROM_HERE, |
1109 base::Bind(&Transfer::Submit, base::Unretained(transfer.release()))); | 1110 base::Bind(&Transfer::Submit, base::Unretained(transfer.release()))); |
1110 } | 1111 } |
1111 | 1112 |
1112 void UsbDeviceHandleImpl::TransferComplete(Transfer* transfer, | 1113 void UsbDeviceHandleImpl::TransferComplete(Transfer* transfer, |
1113 const base::Closure& callback) { | 1114 const base::Closure& callback) { |
1114 DCHECK(thread_checker_.CalledOnValidThread()); | 1115 DCHECK(thread_checker_.CalledOnValidThread()); |
1115 DCHECK(ContainsKey(transfers_, transfer)) << "Missing transfer completed"; | 1116 DCHECK(ContainsKey(transfers_, transfer)) << "Missing transfer completed"; |
1116 transfers_.erase(transfer); | 1117 transfers_.erase(transfer); |
1117 | 1118 |
1118 if (transfer->callback_task_runner()->RunsTasksOnCurrentThread()) { | 1119 if (transfer->callback_task_runner()->RunsTasksOnCurrentThread()) { |
1119 callback.Run(); | 1120 callback.Run(); |
1120 } else { | 1121 } else { |
1121 transfer->callback_task_runner()->PostTask(FROM_HERE, callback); | 1122 transfer->callback_task_runner()->PostTask(FROM_HERE, callback); |
1122 } | 1123 } |
1123 | 1124 |
1124 // libusb_free_transfer races with libusb_submit_transfer and only work- | 1125 // libusb_free_transfer races with libusb_submit_transfer and only work- |
1125 // around is to make sure to call them on the same thread. | 1126 // around is to make sure to call them on the same thread. |
1126 blocking_task_runner_->DeleteSoon(FROM_HERE, transfer); | 1127 blocking_task_runner_->DeleteSoon(FROM_HERE, transfer); |
1127 } | 1128 } |
1128 | 1129 |
1129 } // namespace device | 1130 } // namespace device |
OLD | NEW |