| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/mojo/device_impl.h" | 5 #include "device/usb/mojo/device_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <memory> |
| 10 #include <numeric> | 11 #include <numeric> |
| 11 #include <utility> | 12 #include <utility> |
| 12 #include <vector> | 13 #include <vector> |
| 13 | 14 |
| 14 #include "base/bind.h" | 15 #include "base/bind.h" |
| 15 #include "base/callback.h" | 16 #include "base/callback.h" |
| 17 #include "base/memory/ptr_util.h" |
| 16 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
| 17 #include "device/usb/mojo/type_converters.h" | 19 #include "device/usb/mojo/type_converters.h" |
| 18 #include "device/usb/usb_descriptors.h" | 20 #include "device/usb/usb_descriptors.h" |
| 19 #include "device/usb/usb_device.h" | 21 #include "device/usb/usb_device.h" |
| 20 #include "net/base/io_buffer.h" | 22 #include "net/base/io_buffer.h" |
| 21 | 23 |
| 22 namespace device { | 24 namespace device { |
| 23 namespace usb { | 25 namespace usb { |
| 24 | 26 |
| 25 namespace { | 27 namespace { |
| 26 | 28 |
| 27 using MojoTransferInCallback = | 29 using MojoTransferInCallback = |
| 28 mojo::Callback<void(TransferStatus, mojo::Array<uint8_t>)>; | 30 mojo::Callback<void(TransferStatus, mojo::Array<uint8_t>)>; |
| 29 | 31 |
| 30 using MojoTransferOutCallback = mojo::Callback<void(TransferStatus)>; | 32 using MojoTransferOutCallback = mojo::Callback<void(TransferStatus)>; |
| 31 | 33 |
| 32 template <typename... Args> | 34 template <typename... Args> |
| 33 void CallMojoCallback(scoped_ptr<mojo::Callback<void(Args...)>> callback, | 35 void CallMojoCallback(std::unique_ptr<mojo::Callback<void(Args...)>> callback, |
| 34 Args... args) { | 36 Args... args) { |
| 35 callback->Run(args...); | 37 callback->Run(args...); |
| 36 } | 38 } |
| 37 | 39 |
| 38 // Generic wrapper to convert a Mojo callback to something we can rebind and | 40 // Generic wrapper to convert a Mojo callback to something we can rebind and |
| 39 // pass around. This is only usable for callbacks with no move-only arguments. | 41 // pass around. This is only usable for callbacks with no move-only arguments. |
| 40 template <typename... Args> | 42 template <typename... Args> |
| 41 base::Callback<void(Args...)> WrapMojoCallback( | 43 base::Callback<void(Args...)> WrapMojoCallback( |
| 42 const mojo::Callback<void(Args...)>& callback) { | 44 const mojo::Callback<void(Args...)>& callback) { |
| 43 // mojo::Callback is not thread safe. By wrapping |callback| in a scoped_ptr | 45 // mojo::Callback is not thread safe. By wrapping |callback| in a scoped_ptr |
| 44 // we guarantee that it will be freed when CallMojoCallback is run and not | 46 // we guarantee that it will be freed when CallMojoCallback is run and not |
| 45 // retained until the base::Callback is destroyed, which could happen on any | 47 // retained until the base::Callback is destroyed, which could happen on any |
| 46 // thread. This pattern is also used below in places where this generic | 48 // thread. This pattern is also used below in places where this generic |
| 47 // wrapper is not used. | 49 // wrapper is not used. |
| 48 auto callback_ptr = | 50 auto callback_ptr = |
| 49 make_scoped_ptr(new mojo::Callback<void(Args...)>(callback)); | 51 base::WrapUnique(new mojo::Callback<void(Args...)>(callback)); |
| 50 return base::Bind(&CallMojoCallback<Args...>, base::Passed(&callback_ptr)); | 52 return base::Bind(&CallMojoCallback<Args...>, base::Passed(&callback_ptr)); |
| 51 } | 53 } |
| 52 | 54 |
| 53 scoped_refptr<net::IOBuffer> CreateTransferBuffer(size_t size) { | 55 scoped_refptr<net::IOBuffer> CreateTransferBuffer(size_t size) { |
| 54 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer( | 56 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer( |
| 55 std::max(static_cast<size_t>(1u), static_cast<size_t>(size))); | 57 std::max(static_cast<size_t>(1u), static_cast<size_t>(size))); |
| 56 return buffer; | 58 return buffer; |
| 57 } | 59 } |
| 58 | 60 |
| 59 void OnTransferIn(scoped_ptr<MojoTransferInCallback> callback, | 61 void OnTransferIn(std::unique_ptr<MojoTransferInCallback> callback, |
| 60 UsbTransferStatus status, | 62 UsbTransferStatus status, |
| 61 scoped_refptr<net::IOBuffer> buffer, | 63 scoped_refptr<net::IOBuffer> buffer, |
| 62 size_t buffer_size) { | 64 size_t buffer_size) { |
| 63 mojo::Array<uint8_t> data; | 65 mojo::Array<uint8_t> data; |
| 64 if (buffer) { | 66 if (buffer) { |
| 65 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a | 67 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a |
| 66 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move | 68 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move |
| 67 // instead of copy. | 69 // instead of copy. |
| 68 std::vector<uint8_t> bytes(buffer_size); | 70 std::vector<uint8_t> bytes(buffer_size); |
| 69 std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin()); | 71 std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin()); |
| 70 data.Swap(&bytes); | 72 data.Swap(&bytes); |
| 71 } | 73 } |
| 72 callback->Run(mojo::ConvertTo<TransferStatus>(status), std::move(data)); | 74 callback->Run(mojo::ConvertTo<TransferStatus>(status), std::move(data)); |
| 73 } | 75 } |
| 74 | 76 |
| 75 void OnTransferOut(scoped_ptr<MojoTransferOutCallback> callback, | 77 void OnTransferOut(std::unique_ptr<MojoTransferOutCallback> callback, |
| 76 UsbTransferStatus status, | 78 UsbTransferStatus status, |
| 77 scoped_refptr<net::IOBuffer> buffer, | 79 scoped_refptr<net::IOBuffer> buffer, |
| 78 size_t buffer_size) { | 80 size_t buffer_size) { |
| 79 callback->Run(mojo::ConvertTo<TransferStatus>(status)); | 81 callback->Run(mojo::ConvertTo<TransferStatus>(status)); |
| 80 } | 82 } |
| 81 | 83 |
| 82 mojo::Array<IsochronousPacketPtr> BuildIsochronousPacketArray( | 84 mojo::Array<IsochronousPacketPtr> BuildIsochronousPacketArray( |
| 83 mojo::Array<uint32_t> packet_lengths, | 85 mojo::Array<uint32_t> packet_lengths, |
| 84 TransferStatus status) { | 86 TransferStatus status) { |
| 85 mojo::Array<IsochronousPacketPtr> packets(packet_lengths.size()); | 87 mojo::Array<IsochronousPacketPtr> packets(packet_lengths.size()); |
| 86 for (size_t i = 0; i < packet_lengths.size(); ++i) { | 88 for (size_t i = 0; i < packet_lengths.size(); ++i) { |
| 87 packets[i] = IsochronousPacket::New(); | 89 packets[i] = IsochronousPacket::New(); |
| 88 packets[i]->length = packet_lengths[i]; | 90 packets[i]->length = packet_lengths[i]; |
| 89 packets[i]->status = status; | 91 packets[i]->status = status; |
| 90 } | 92 } |
| 91 return packets; | 93 return packets; |
| 92 } | 94 } |
| 93 | 95 |
| 94 void OnIsochronousTransferIn( | 96 void OnIsochronousTransferIn( |
| 95 scoped_ptr<Device::IsochronousTransferInCallback> callback, | 97 std::unique_ptr<Device::IsochronousTransferInCallback> callback, |
| 96 scoped_refptr<net::IOBuffer> buffer, | 98 scoped_refptr<net::IOBuffer> buffer, |
| 97 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { | 99 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { |
| 98 mojo::Array<uint8_t> data; | 100 mojo::Array<uint8_t> data; |
| 99 if (buffer) { | 101 if (buffer) { |
| 100 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a | 102 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a |
| 101 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move | 103 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move |
| 102 // instead of copy. | 104 // instead of copy. |
| 103 uint32_t buffer_size = | 105 uint32_t buffer_size = |
| 104 std::accumulate(packets.begin(), packets.end(), 0u, | 106 std::accumulate(packets.begin(), packets.end(), 0u, |
| 105 [](const uint32_t& a, | 107 [](const uint32_t& a, |
| 106 const UsbDeviceHandle::IsochronousPacket& packet) { | 108 const UsbDeviceHandle::IsochronousPacket& packet) { |
| 107 return a + packet.length; | 109 return a + packet.length; |
| 108 }); | 110 }); |
| 109 std::vector<uint8_t> bytes(buffer_size); | 111 std::vector<uint8_t> bytes(buffer_size); |
| 110 std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin()); | 112 std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin()); |
| 111 data.Swap(&bytes); | 113 data.Swap(&bytes); |
| 112 } | 114 } |
| 113 callback->Run(std::move(data), | 115 callback->Run(std::move(data), |
| 114 mojo::Array<IsochronousPacketPtr>::From(packets)); | 116 mojo::Array<IsochronousPacketPtr>::From(packets)); |
| 115 } | 117 } |
| 116 | 118 |
| 117 void OnIsochronousTransferOut( | 119 void OnIsochronousTransferOut( |
| 118 scoped_ptr<Device::IsochronousTransferOutCallback> callback, | 120 std::unique_ptr<Device::IsochronousTransferOutCallback> callback, |
| 119 scoped_refptr<net::IOBuffer> buffer, | 121 scoped_refptr<net::IOBuffer> buffer, |
| 120 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { | 122 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { |
| 121 callback->Run(mojo::Array<IsochronousPacketPtr>::From(packets)); | 123 callback->Run(mojo::Array<IsochronousPacketPtr>::From(packets)); |
| 122 } | 124 } |
| 123 | 125 |
| 124 } // namespace | 126 } // namespace |
| 125 | 127 |
| 126 DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device, | 128 DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device, |
| 127 DeviceInfoPtr device_info, | 129 DeviceInfoPtr device_info, |
| 128 base::WeakPtr<PermissionProvider> permission_provider, | 130 base::WeakPtr<PermissionProvider> permission_provider, |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 uint32_t timeout, | 320 uint32_t timeout, |
| 319 const ControlTransferInCallback& callback) { | 321 const ControlTransferInCallback& callback) { |
| 320 if (!device_handle_) { | 322 if (!device_handle_) { |
| 321 callback.Run(TransferStatus::TRANSFER_ERROR, mojo::Array<uint8_t>()); | 323 callback.Run(TransferStatus::TRANSFER_ERROR, mojo::Array<uint8_t>()); |
| 322 return; | 324 return; |
| 323 } | 325 } |
| 324 | 326 |
| 325 if (HasControlTransferPermission(params->recipient, params->index)) { | 327 if (HasControlTransferPermission(params->recipient, params->index)) { |
| 326 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); | 328 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); |
| 327 auto callback_ptr = | 329 auto callback_ptr = |
| 328 make_scoped_ptr(new ControlTransferInCallback(callback)); | 330 base::WrapUnique(new ControlTransferInCallback(callback)); |
| 329 device_handle_->ControlTransfer( | 331 device_handle_->ControlTransfer( |
| 330 USB_DIRECTION_INBOUND, | 332 USB_DIRECTION_INBOUND, |
| 331 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), | 333 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), |
| 332 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), | 334 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), |
| 333 params->request, params->value, params->index, buffer, length, timeout, | 335 params->request, params->value, params->index, buffer, length, timeout, |
| 334 base::Bind(&OnTransferIn, base::Passed(&callback_ptr))); | 336 base::Bind(&OnTransferIn, base::Passed(&callback_ptr))); |
| 335 } else { | 337 } else { |
| 336 mojo::Array<uint8_t> data; | 338 mojo::Array<uint8_t> data; |
| 337 callback.Run(TransferStatus::PERMISSION_DENIED, std::move(data)); | 339 callback.Run(TransferStatus::PERMISSION_DENIED, std::move(data)); |
| 338 } | 340 } |
| 339 } | 341 } |
| 340 | 342 |
| 341 void DeviceImpl::ControlTransferOut( | 343 void DeviceImpl::ControlTransferOut( |
| 342 ControlTransferParamsPtr params, | 344 ControlTransferParamsPtr params, |
| 343 mojo::Array<uint8_t> data, | 345 mojo::Array<uint8_t> data, |
| 344 uint32_t timeout, | 346 uint32_t timeout, |
| 345 const ControlTransferOutCallback& callback) { | 347 const ControlTransferOutCallback& callback) { |
| 346 if (!device_handle_) { | 348 if (!device_handle_) { |
| 347 callback.Run(TransferStatus::TRANSFER_ERROR); | 349 callback.Run(TransferStatus::TRANSFER_ERROR); |
| 348 return; | 350 return; |
| 349 } | 351 } |
| 350 | 352 |
| 351 if (HasControlTransferPermission(params->recipient, params->index)) { | 353 if (HasControlTransferPermission(params->recipient, params->index)) { |
| 352 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); | 354 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); |
| 353 const std::vector<uint8_t>& storage = data.storage(); | 355 const std::vector<uint8_t>& storage = data.storage(); |
| 354 std::copy(storage.begin(), storage.end(), buffer->data()); | 356 std::copy(storage.begin(), storage.end(), buffer->data()); |
| 355 auto callback_ptr = | 357 auto callback_ptr = |
| 356 make_scoped_ptr(new ControlTransferOutCallback(callback)); | 358 base::WrapUnique(new ControlTransferOutCallback(callback)); |
| 357 device_handle_->ControlTransfer( | 359 device_handle_->ControlTransfer( |
| 358 USB_DIRECTION_OUTBOUND, | 360 USB_DIRECTION_OUTBOUND, |
| 359 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), | 361 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), |
| 360 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), | 362 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), |
| 361 params->request, params->value, params->index, buffer, data.size(), | 363 params->request, params->value, params->index, buffer, data.size(), |
| 362 timeout, base::Bind(&OnTransferOut, base::Passed(&callback_ptr))); | 364 timeout, base::Bind(&OnTransferOut, base::Passed(&callback_ptr))); |
| 363 } else { | 365 } else { |
| 364 callback.Run(TransferStatus::PERMISSION_DENIED); | 366 callback.Run(TransferStatus::PERMISSION_DENIED); |
| 365 } | 367 } |
| 366 } | 368 } |
| 367 | 369 |
| 368 void DeviceImpl::GenericTransferIn(uint8_t endpoint_number, | 370 void DeviceImpl::GenericTransferIn(uint8_t endpoint_number, |
| 369 uint32_t length, | 371 uint32_t length, |
| 370 uint32_t timeout, | 372 uint32_t timeout, |
| 371 const GenericTransferInCallback& callback) { | 373 const GenericTransferInCallback& callback) { |
| 372 if (!device_handle_) { | 374 if (!device_handle_) { |
| 373 callback.Run(TransferStatus::TRANSFER_ERROR, mojo::Array<uint8_t>()); | 375 callback.Run(TransferStatus::TRANSFER_ERROR, mojo::Array<uint8_t>()); |
| 374 return; | 376 return; |
| 375 } | 377 } |
| 376 | 378 |
| 377 auto callback_ptr = make_scoped_ptr(new GenericTransferInCallback(callback)); | 379 auto callback_ptr = base::WrapUnique(new GenericTransferInCallback(callback)); |
| 378 uint8_t endpoint_address = endpoint_number | 0x80; | 380 uint8_t endpoint_address = endpoint_number | 0x80; |
| 379 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); | 381 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); |
| 380 device_handle_->GenericTransfer( | 382 device_handle_->GenericTransfer( |
| 381 USB_DIRECTION_INBOUND, endpoint_address, buffer, length, timeout, | 383 USB_DIRECTION_INBOUND, endpoint_address, buffer, length, timeout, |
| 382 base::Bind(&OnTransferIn, base::Passed(&callback_ptr))); | 384 base::Bind(&OnTransferIn, base::Passed(&callback_ptr))); |
| 383 } | 385 } |
| 384 | 386 |
| 385 void DeviceImpl::GenericTransferOut( | 387 void DeviceImpl::GenericTransferOut( |
| 386 uint8_t endpoint_number, | 388 uint8_t endpoint_number, |
| 387 mojo::Array<uint8_t> data, | 389 mojo::Array<uint8_t> data, |
| 388 uint32_t timeout, | 390 uint32_t timeout, |
| 389 const GenericTransferOutCallback& callback) { | 391 const GenericTransferOutCallback& callback) { |
| 390 if (!device_handle_) { | 392 if (!device_handle_) { |
| 391 callback.Run(TransferStatus::TRANSFER_ERROR); | 393 callback.Run(TransferStatus::TRANSFER_ERROR); |
| 392 return; | 394 return; |
| 393 } | 395 } |
| 394 | 396 |
| 395 auto callback_ptr = make_scoped_ptr(new GenericTransferOutCallback(callback)); | 397 auto callback_ptr = |
| 398 base::WrapUnique(new GenericTransferOutCallback(callback)); |
| 396 uint8_t endpoint_address = endpoint_number; | 399 uint8_t endpoint_address = endpoint_number; |
| 397 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); | 400 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); |
| 398 const std::vector<uint8_t>& storage = data.storage(); | 401 const std::vector<uint8_t>& storage = data.storage(); |
| 399 std::copy(storage.begin(), storage.end(), buffer->data()); | 402 std::copy(storage.begin(), storage.end(), buffer->data()); |
| 400 device_handle_->GenericTransfer( | 403 device_handle_->GenericTransfer( |
| 401 USB_DIRECTION_OUTBOUND, endpoint_address, buffer, data.size(), timeout, | 404 USB_DIRECTION_OUTBOUND, endpoint_address, buffer, data.size(), timeout, |
| 402 base::Bind(&OnTransferOut, base::Passed(&callback_ptr))); | 405 base::Bind(&OnTransferOut, base::Passed(&callback_ptr))); |
| 403 } | 406 } |
| 404 | 407 |
| 405 void DeviceImpl::IsochronousTransferIn( | 408 void DeviceImpl::IsochronousTransferIn( |
| 406 uint8_t endpoint_number, | 409 uint8_t endpoint_number, |
| 407 mojo::Array<uint32_t> packet_lengths, | 410 mojo::Array<uint32_t> packet_lengths, |
| 408 uint32_t timeout, | 411 uint32_t timeout, |
| 409 const IsochronousTransferInCallback& callback) { | 412 const IsochronousTransferInCallback& callback) { |
| 410 if (!device_handle_) { | 413 if (!device_handle_) { |
| 411 callback.Run(mojo::Array<uint8_t>(), | 414 callback.Run(mojo::Array<uint8_t>(), |
| 412 BuildIsochronousPacketArray(std::move(packet_lengths), | 415 BuildIsochronousPacketArray(std::move(packet_lengths), |
| 413 TransferStatus::TRANSFER_ERROR)); | 416 TransferStatus::TRANSFER_ERROR)); |
| 414 return; | 417 return; |
| 415 } | 418 } |
| 416 | 419 |
| 417 auto callback_ptr = | 420 auto callback_ptr = |
| 418 make_scoped_ptr(new IsochronousTransferInCallback(callback)); | 421 base::WrapUnique(new IsochronousTransferInCallback(callback)); |
| 419 uint8_t endpoint_address = endpoint_number | 0x80; | 422 uint8_t endpoint_address = endpoint_number | 0x80; |
| 420 device_handle_->IsochronousTransferIn( | 423 device_handle_->IsochronousTransferIn( |
| 421 endpoint_address, packet_lengths.storage(), timeout, | 424 endpoint_address, packet_lengths.storage(), timeout, |
| 422 base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr))); | 425 base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr))); |
| 423 } | 426 } |
| 424 | 427 |
| 425 void DeviceImpl::IsochronousTransferOut( | 428 void DeviceImpl::IsochronousTransferOut( |
| 426 uint8_t endpoint_number, | 429 uint8_t endpoint_number, |
| 427 mojo::Array<uint8_t> data, | 430 mojo::Array<uint8_t> data, |
| 428 mojo::Array<uint32_t> packet_lengths, | 431 mojo::Array<uint32_t> packet_lengths, |
| 429 uint32_t timeout, | 432 uint32_t timeout, |
| 430 const IsochronousTransferOutCallback& callback) { | 433 const IsochronousTransferOutCallback& callback) { |
| 431 if (!device_handle_) { | 434 if (!device_handle_) { |
| 432 callback.Run(BuildIsochronousPacketArray(std::move(packet_lengths), | 435 callback.Run(BuildIsochronousPacketArray(std::move(packet_lengths), |
| 433 TransferStatus::TRANSFER_ERROR)); | 436 TransferStatus::TRANSFER_ERROR)); |
| 434 return; | 437 return; |
| 435 } | 438 } |
| 436 | 439 |
| 437 auto callback_ptr = | 440 auto callback_ptr = |
| 438 make_scoped_ptr(new IsochronousTransferOutCallback(callback)); | 441 base::WrapUnique(new IsochronousTransferOutCallback(callback)); |
| 439 uint8_t endpoint_address = endpoint_number; | 442 uint8_t endpoint_address = endpoint_number; |
| 440 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); | 443 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); |
| 441 { | 444 { |
| 442 const std::vector<uint8_t>& storage = data.storage(); | 445 const std::vector<uint8_t>& storage = data.storage(); |
| 443 std::copy(storage.begin(), storage.end(), buffer->data()); | 446 std::copy(storage.begin(), storage.end(), buffer->data()); |
| 444 } | 447 } |
| 445 device_handle_->IsochronousTransferOut( | 448 device_handle_->IsochronousTransferOut( |
| 446 endpoint_address, buffer, packet_lengths.storage(), timeout, | 449 endpoint_address, buffer, packet_lengths.storage(), timeout, |
| 447 base::Bind(&OnIsochronousTransferOut, base::Passed(&callback_ptr))); | 450 base::Bind(&OnIsochronousTransferOut, base::Passed(&callback_ptr))); |
| 448 } | 451 } |
| 449 | 452 |
| 450 void DeviceImpl::OnDeviceRemoved(scoped_refptr<UsbDevice> device) { | 453 void DeviceImpl::OnDeviceRemoved(scoped_refptr<UsbDevice> device) { |
| 451 DCHECK_EQ(device_, device); | 454 DCHECK_EQ(device_, device); |
| 452 delete this; | 455 delete this; |
| 453 } | 456 } |
| 454 | 457 |
| 455 } // namespace usb | 458 } // namespace usb |
| 456 } // namespace device | 459 } // namespace device |
| OLD | NEW |