Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: extensions/browser/api/usb/usb_api.cc

Issue 1618393004: Update device/usb and its Mojo interface for variable size ISO packets. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "extensions/browser/api/usb/usb_api.h" 5 #include "extensions/browser/api/usb/usb_api.h"
6 6
7 #include <algorithm>
8 #include <numeric>
7 #include <string> 9 #include <string>
8 #include <utility> 10 #include <utility>
9 #include <vector> 11 #include <vector>
10 12
11 #include "base/barrier_closure.h" 13 #include "base/barrier_closure.h"
12 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
13 #include "device/core/device_client.h" 15 #include "device/core/device_client.h"
14 #include "device/usb/usb_descriptors.h" 16 #include "device/usb/usb_descriptors.h"
15 #include "device/usb/usb_device_handle.h" 17 #include "device/usb/usb_device_handle.h"
16 #include "device/usb/usb_service.h" 18 #include "device/usb/usb_service.h"
(...skipping 1110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 GetDeviceHandle(parameters->handle); 1129 GetDeviceHandle(parameters->handle);
1128 if (!device_handle.get()) { 1130 if (!device_handle.get()) {
1129 return RespondNow(Error(kErrorNoConnection)); 1131 return RespondNow(Error(kErrorNoConnection));
1130 } 1132 }
1131 1133
1132 const IsochronousTransferInfo& transfer = parameters->transfer_info; 1134 const IsochronousTransferInfo& transfer = parameters->transfer_info;
1133 const GenericTransferInfo& generic_transfer = transfer.transfer_info; 1135 const GenericTransferInfo& generic_transfer = transfer.transfer_info;
1134 size_t size = 0; 1136 size_t size = 0;
1135 UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND; 1137 UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND;
1136 1138
1137 if (!ConvertDirectionFromApi(generic_transfer.direction, &direction)) { 1139 if (!ConvertDirectionFromApi(generic_transfer.direction, &direction))
1138 return RespondNow(Error(kErrorConvertDirection)); 1140 return RespondNow(Error(kErrorConvertDirection));
1139 }
1140 1141
1141 if (!GetTransferSize(generic_transfer, &size)) { 1142 if (!GetTransferSize(generic_transfer, &size))
1142 return RespondNow(Error(kErrorInvalidTransferLength)); 1143 return RespondNow(Error(kErrorInvalidTransferLength));
1143 }
1144 1144
1145 if (transfer.packets < 0 || transfer.packets >= kMaxPackets) { 1145 if (transfer.packets < 0 || transfer.packets >= kMaxPackets)
1146 return RespondNow(Error(kErrorInvalidNumberOfPackets)); 1146 return RespondNow(Error(kErrorInvalidNumberOfPackets));
1147 } 1147 size_t packets = transfer.packets;
1148 1148
1149 unsigned int packets = transfer.packets;
1150 if (transfer.packet_length < 0 || 1149 if (transfer.packet_length < 0 ||
1151 transfer.packet_length >= kMaxPacketLength) { 1150 transfer.packet_length >= kMaxPacketLength) {
1152 return RespondNow(Error(kErrorInvalidPacketLength)); 1151 return RespondNow(Error(kErrorInvalidPacketLength));
1153 } 1152 }
1154 1153
1155 unsigned int packet_length = transfer.packet_length; 1154 size_t total_length = packets * transfer.packet_length;
1156 const uint64_t total_length = packets * packet_length; 1155 if (packets > size || total_length > size)
1157 if (packets > size || total_length > size) {
1158 return RespondNow(Error(kErrorTransferLength)); 1156 return RespondNow(Error(kErrorTransferLength));
1157 std::vector<uint32_t> packet_lengths(packets, transfer.packet_length);
1158
1159 int timeout = generic_transfer.timeout ? *generic_transfer.timeout : 0;
1160 if (timeout < 0)
1161 return RespondNow(Error(kErrorInvalidTimeout));
1162
1163 if (direction == device::USB_DIRECTION_INBOUND) {
1164 device_handle->IsochronousTransferIn(
1165 generic_transfer.endpoint, packet_lengths, timeout,
1166 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this));
1167 } else {
1168 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
1169 generic_transfer, direction, transfer.packets * transfer.packet_length);
1170 if (!buffer.get())
1171 return RespondNow(Error(kErrorMalformedParameters));
1172
1173 device_handle->IsochronousTransferOut(
1174 generic_transfer.endpoint, buffer.get(), packet_lengths, timeout,
1175 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this));
1176 }
1177 return RespondLater();
1178 }
1179
1180 void UsbIsochronousTransferFunction::OnCompleted(
1181 scoped_refptr<net::IOBuffer> data,
1182 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) {
1183 size_t length = std::accumulate(
1184 packets.begin(), packets.end(), 0,
1185 [](const size_t& a, const UsbDeviceHandle::IsochronousPacket& packet) {
1186 return a + packet.transferred_length;
1187 });
1188 scoped_ptr<char[]> buffer(new char[length]);
1189
1190 UsbTransferStatus status = device::USB_TRANSFER_COMPLETED;
1191 size_t buffer_offset = 0;
1192 size_t data_offset = 0;
1193 for (const auto& packet : packets) {
scheib 2016/01/27 01:42:13 test for an example of an error here.
Reilly Grant (use Gerrit) 2016/01/29 23:25:36 Done.
1194 // Capture the error status of the first unsuccessful packet.
1195 if (status == device::USB_TRANSFER_COMPLETED &&
1196 packet.status != device::USB_TRANSFER_COMPLETED) {
1197 status = packet.status;
1198 }
1199
1200 memcpy(&buffer[buffer_offset], data->data() + data_offset,
scheib 2016/01/27 01:42:13 Is there test coverage for this API bindings code?
Reilly Grant (use Gerrit) 2016/01/29 23:25:36 Yes, in //extensions/test/data/api_test/usb.
1201 packet.transferred_length);
1202 buffer_offset += packet.transferred_length;
1203 data_offset += packet.length;
1159 } 1204 }
1160 1205
1161 scoped_refptr<net::IOBuffer> buffer = 1206 scoped_ptr<base::DictionaryValue> transfer_info(new base::DictionaryValue());
1162 CreateBufferForTransfer(generic_transfer, direction, size); 1207 transfer_info->SetInteger(kResultCodeKey, status);
1163 if (!buffer.get()) { 1208 transfer_info->Set(kDataKey,
1164 return RespondNow(Error(kErrorMalformedParameters)); 1209 new base::BinaryValue(std::move(buffer), length));
1210 if (status == device::USB_TRANSFER_COMPLETED) {
1211 Respond(OneArgument(std::move(transfer_info)));
1212 } else {
1213 scoped_ptr<base::ListValue> error_args(new base::ListValue());
1214 error_args->Append(std::move(transfer_info));
1215 // Returning arguments with an error is wrong but we're stuck with it.
scheib 2016/01/27 01:42:13 'wrong'? why? deprecated?
Reilly Grant (use Gerrit) 2016/01/29 23:25:36 It wasn't supposed to work but it does and some AP
scheib 2016/01/30 22:01:06 Please explain it in the code comment.
1216 Respond(ErrorWithArguments(std::move(error_args),
1217 ConvertTransferStatusToApi(status)));
1165 } 1218 }
1166
1167 int timeout = generic_transfer.timeout ? *generic_transfer.timeout : 0;
1168 if (timeout < 0) {
1169 return RespondNow(Error(kErrorInvalidTimeout));
1170 }
1171
1172 device_handle->IsochronousTransfer(
1173 direction, generic_transfer.endpoint, buffer.get(), size, packets,
1174 packet_length, timeout,
1175 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this));
1176 return RespondLater();
1177 } 1219 }
1178 1220
1179 UsbResetDeviceFunction::UsbResetDeviceFunction() { 1221 UsbResetDeviceFunction::UsbResetDeviceFunction() {
1180 } 1222 }
1181 1223
1182 UsbResetDeviceFunction::~UsbResetDeviceFunction() { 1224 UsbResetDeviceFunction::~UsbResetDeviceFunction() {
1183 } 1225 }
1184 1226
1185 ExtensionFunction::ResponseAction UsbResetDeviceFunction::Run() { 1227 ExtensionFunction::ResponseAction UsbResetDeviceFunction::Run() {
1186 parameters_ = ResetDevice::Params::Create(*args_); 1228 parameters_ = ResetDevice::Params::Create(*args_);
(...skipping 22 matching lines...) Expand all
1209 ReleaseDeviceHandle(parameters_->handle); 1251 ReleaseDeviceHandle(parameters_->handle);
1210 1252
1211 scoped_ptr<base::ListValue> error_args(new base::ListValue()); 1253 scoped_ptr<base::ListValue> error_args(new base::ListValue());
1212 error_args->AppendBoolean(false); 1254 error_args->AppendBoolean(false);
1213 // Returning arguments with an error is wrong but we're stuck with it. 1255 // Returning arguments with an error is wrong but we're stuck with it.
1214 Respond(ErrorWithArguments(std::move(error_args), kErrorResetDevice)); 1256 Respond(ErrorWithArguments(std::move(error_args), kErrorResetDevice));
1215 } 1257 }
1216 } 1258 }
1217 1259
1218 } // namespace extensions 1260 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698