| Index: device/devices_app/usb/device_impl.cc
|
| diff --git a/device/devices_app/usb/device_impl.cc b/device/devices_app/usb/device_impl.cc
|
| index fd2f0ff6bc5c1abf7adf3a9f9887a313ad9863e9..ae8ad40a4e09e4d50ac9bffb03a47b721f2174af 100644
|
| --- a/device/devices_app/usb/device_impl.cc
|
| +++ b/device/devices_app/usb/device_impl.cc
|
| @@ -5,7 +5,11 @@
|
| #include "device/devices_app/usb/device_impl.h"
|
|
|
| #include <stddef.h>
|
| +
|
| +#include <algorithm>
|
| +#include <numeric>
|
| #include <utility>
|
| +#include <vector>
|
|
|
| #include "base/bind.h"
|
| #include "base/callback.h"
|
| @@ -128,32 +132,46 @@ void OnControlTransferOutPermissionCheckComplete(
|
| }
|
| }
|
|
|
| +mojo::Array<IsochronousPacketPtr> BuildIsochronousPacketArray(
|
| + mojo::Array<uint32_t> packet_lengths,
|
| + TransferStatus status) {
|
| + mojo::Array<IsochronousPacketPtr> packets(packet_lengths.size());
|
| + for (size_t i = 0; i < packet_lengths.size(); ++i) {
|
| + packets[i] = IsochronousPacket::New();
|
| + packets[i]->length = packet_lengths[i];
|
| + packets[i]->status = status;
|
| + }
|
| + return packets;
|
| +}
|
| +
|
| void OnIsochronousTransferIn(
|
| scoped_ptr<Device::IsochronousTransferInCallback> callback,
|
| - uint32_t packet_size,
|
| - UsbTransferStatus status,
|
| scoped_refptr<net::IOBuffer> buffer,
|
| - size_t buffer_size) {
|
| - size_t num_packets = buffer_size / packet_size;
|
| - mojo::Array<mojo::Array<uint8_t>> packets(num_packets);
|
| + const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) {
|
| + mojo::Array<uint8_t> data;
|
| if (buffer) {
|
| - for (size_t i = 0; i < num_packets; ++i) {
|
| - size_t packet_index = i * packet_size;
|
| - std::vector<uint8_t> bytes(packet_size);
|
| - std::copy(buffer->data() + packet_index,
|
| - buffer->data() + packet_index + packet_size, bytes.begin());
|
| - packets[i].Swap(&bytes);
|
| - }
|
| + // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a
|
| + // std::vector<uint8_t> instead of net::IOBuffer. Then we could move
|
| + // instead of copy.
|
| + uint32_t buffer_size =
|
| + std::accumulate(packets.begin(), packets.end(), 0u,
|
| + [](const uint32_t& a,
|
| + const UsbDeviceHandle::IsochronousPacket& packet) {
|
| + return a + packet.length;
|
| + });
|
| + std::vector<uint8_t> bytes(buffer_size);
|
| + std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin());
|
| + data.Swap(&bytes);
|
| }
|
| - callback->Run(mojo::ConvertTo<TransferStatus>(status), std::move(packets));
|
| + callback->Run(std::move(data),
|
| + mojo::Array<IsochronousPacketPtr>::From(packets));
|
| }
|
|
|
| void OnIsochronousTransferOut(
|
| scoped_ptr<Device::IsochronousTransferOutCallback> callback,
|
| - UsbTransferStatus status,
|
| scoped_refptr<net::IOBuffer> buffer,
|
| - size_t buffer_size) {
|
| - callback->Run(mojo::ConvertTo<TransferStatus>(status));
|
| + const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) {
|
| + callback->Run(mojo::Array<IsochronousPacketPtr>::From(packets));
|
| }
|
|
|
| } // namespace
|
| @@ -398,58 +416,46 @@ void DeviceImpl::GenericTransferOut(
|
|
|
| void DeviceImpl::IsochronousTransferIn(
|
| uint8_t endpoint_number,
|
| - uint32_t num_packets,
|
| - uint32_t packet_length,
|
| + mojo::Array<uint32_t> packet_lengths,
|
| uint32_t timeout,
|
| const IsochronousTransferInCallback& callback) {
|
| if (!device_handle_) {
|
| - callback.Run(TransferStatus::TRANSFER_ERROR,
|
| - mojo::Array<mojo::Array<uint8_t>>());
|
| + callback.Run(mojo::Array<uint8_t>(),
|
| + BuildIsochronousPacketArray(std::move(packet_lengths),
|
| + TransferStatus::TRANSFER_ERROR));
|
| return;
|
| }
|
|
|
| auto callback_ptr =
|
| make_scoped_ptr(new IsochronousTransferInCallback(callback));
|
| uint8_t endpoint_address = endpoint_number | 0x80;
|
| - size_t transfer_size = static_cast<size_t>(num_packets) * packet_length;
|
| - scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(transfer_size);
|
| - device_handle_->IsochronousTransfer(
|
| - USB_DIRECTION_INBOUND, endpoint_address, buffer, transfer_size,
|
| - num_packets, packet_length, timeout,
|
| - base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr),
|
| - packet_length));
|
| + device_handle_->IsochronousTransferIn(
|
| + endpoint_address, packet_lengths.storage(), timeout,
|
| + base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr)));
|
| }
|
|
|
| void DeviceImpl::IsochronousTransferOut(
|
| uint8_t endpoint_number,
|
| - mojo::Array<mojo::Array<uint8_t>> packets,
|
| + mojo::Array<uint8_t> data,
|
| + mojo::Array<uint32_t> packet_lengths,
|
| uint32_t timeout,
|
| const IsochronousTransferOutCallback& callback) {
|
| if (!device_handle_) {
|
| - callback.Run(TransferStatus::TRANSFER_ERROR);
|
| + callback.Run(BuildIsochronousPacketArray(std::move(packet_lengths),
|
| + TransferStatus::TRANSFER_ERROR));
|
| return;
|
| }
|
|
|
| auto callback_ptr =
|
| make_scoped_ptr(new IsochronousTransferOutCallback(callback));
|
| uint8_t endpoint_address = endpoint_number;
|
| - uint32_t packet_size = 0;
|
| - for (size_t i = 0; i < packets.size(); ++i) {
|
| - packet_size =
|
| - std::max(packet_size, static_cast<uint32_t>(packets[i].size()));
|
| - }
|
| - size_t transfer_size = packet_size * packets.size();
|
| - scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(transfer_size);
|
| - memset(buffer->data(), 0, transfer_size);
|
| - for (size_t i = 0; i < packets.size(); ++i) {
|
| - uint8_t* packet =
|
| - reinterpret_cast<uint8_t*>(&buffer->data()[i * packet_size]);
|
| - DCHECK_LE(packets[i].size(), static_cast<size_t>(packet_size));
|
| - memcpy(packet, packets[i].storage().data(), packets[i].size());
|
| + scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size());
|
| + {
|
| + const std::vector<uint8_t>& storage = data.storage();
|
| + std::copy(storage.begin(), storage.end(), buffer->data());
|
| }
|
| - device_handle_->IsochronousTransfer(
|
| - USB_DIRECTION_OUTBOUND, endpoint_address, buffer, transfer_size,
|
| - static_cast<uint32_t>(packets.size()), packet_size, timeout,
|
| + device_handle_->IsochronousTransferOut(
|
| + endpoint_address, buffer, packet_lengths.storage(), timeout,
|
| base::Bind(&OnIsochronousTransferOut, base::Passed(&callback_ptr)));
|
| }
|
|
|
|
|