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

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: Document use of ErrorWithArguments. Created 4 years, 10 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
« no previous file with comments | « extensions/browser/api/usb/usb_api.h ('k') | extensions/browser/api/usb/usb_apitest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 scoped_ptr<base::DictionaryValue> transfer_info(new base::DictionaryValue()); 463 scoped_ptr<base::DictionaryValue> transfer_info(new base::DictionaryValue());
462 transfer_info->SetInteger(kResultCodeKey, status); 464 transfer_info->SetInteger(kResultCodeKey, status);
463 transfer_info->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer( 465 transfer_info->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer(
464 data->data(), length)); 466 data->data(), length));
465 467
466 if (status == device::USB_TRANSFER_COMPLETED) { 468 if (status == device::USB_TRANSFER_COMPLETED) {
467 Respond(OneArgument(std::move(transfer_info))); 469 Respond(OneArgument(std::move(transfer_info)));
468 } else { 470 } else {
469 scoped_ptr<base::ListValue> error_args(new base::ListValue()); 471 scoped_ptr<base::ListValue> error_args(new base::ListValue());
470 error_args->Append(std::move(transfer_info)); 472 error_args->Append(std::move(transfer_info));
471 // Returning arguments with an error is wrong but we're stuck with it. 473 // Using ErrorWithArguments is discouraged but required to provide the
474 // detailed transfer info as the transfer may have partially succeeded.
472 Respond(ErrorWithArguments(std::move(error_args), 475 Respond(ErrorWithArguments(std::move(error_args),
473 ConvertTransferStatusToApi(status))); 476 ConvertTransferStatusToApi(status)));
474 } 477 }
475 } 478 }
476 479
477 UsbFindDevicesFunction::UsbFindDevicesFunction() { 480 UsbFindDevicesFunction::UsbFindDevicesFunction() {
478 } 481 }
479 482
480 UsbFindDevicesFunction::~UsbFindDevicesFunction() { 483 UsbFindDevicesFunction::~UsbFindDevicesFunction() {
481 } 484 }
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 GetDeviceHandle(parameters->handle); 1130 GetDeviceHandle(parameters->handle);
1128 if (!device_handle.get()) { 1131 if (!device_handle.get()) {
1129 return RespondNow(Error(kErrorNoConnection)); 1132 return RespondNow(Error(kErrorNoConnection));
1130 } 1133 }
1131 1134
1132 const IsochronousTransferInfo& transfer = parameters->transfer_info; 1135 const IsochronousTransferInfo& transfer = parameters->transfer_info;
1133 const GenericTransferInfo& generic_transfer = transfer.transfer_info; 1136 const GenericTransferInfo& generic_transfer = transfer.transfer_info;
1134 size_t size = 0; 1137 size_t size = 0;
1135 UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND; 1138 UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND;
1136 1139
1137 if (!ConvertDirectionFromApi(generic_transfer.direction, &direction)) { 1140 if (!ConvertDirectionFromApi(generic_transfer.direction, &direction))
1138 return RespondNow(Error(kErrorConvertDirection)); 1141 return RespondNow(Error(kErrorConvertDirection));
1139 }
1140 1142
1141 if (!GetTransferSize(generic_transfer, &size)) { 1143 if (!GetTransferSize(generic_transfer, &size))
1142 return RespondNow(Error(kErrorInvalidTransferLength)); 1144 return RespondNow(Error(kErrorInvalidTransferLength));
1143 }
1144 1145
1145 if (transfer.packets < 0 || transfer.packets >= kMaxPackets) { 1146 if (transfer.packets < 0 || transfer.packets >= kMaxPackets)
1146 return RespondNow(Error(kErrorInvalidNumberOfPackets)); 1147 return RespondNow(Error(kErrorInvalidNumberOfPackets));
1147 } 1148 size_t packets = transfer.packets;
1148 1149
1149 unsigned int packets = transfer.packets;
1150 if (transfer.packet_length < 0 || 1150 if (transfer.packet_length < 0 ||
1151 transfer.packet_length >= kMaxPacketLength) { 1151 transfer.packet_length >= kMaxPacketLength) {
1152 return RespondNow(Error(kErrorInvalidPacketLength)); 1152 return RespondNow(Error(kErrorInvalidPacketLength));
1153 } 1153 }
1154 1154
1155 unsigned int packet_length = transfer.packet_length; 1155 size_t total_length = packets * transfer.packet_length;
1156 const uint64_t total_length = packets * packet_length; 1156 if (packets > size || total_length > size)
1157 if (packets > size || total_length > size) {
1158 return RespondNow(Error(kErrorTransferLength)); 1157 return RespondNow(Error(kErrorTransferLength));
1158 std::vector<uint32_t> packet_lengths(packets, transfer.packet_length);
1159
1160 int timeout = generic_transfer.timeout ? *generic_transfer.timeout : 0;
1161 if (timeout < 0)
1162 return RespondNow(Error(kErrorInvalidTimeout));
1163
1164 if (direction == device::USB_DIRECTION_INBOUND) {
1165 device_handle->IsochronousTransferIn(
1166 generic_transfer.endpoint, packet_lengths, timeout,
1167 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this));
1168 } else {
1169 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
1170 generic_transfer, direction, transfer.packets * transfer.packet_length);
1171 if (!buffer.get())
1172 return RespondNow(Error(kErrorMalformedParameters));
1173
1174 device_handle->IsochronousTransferOut(
1175 generic_transfer.endpoint, buffer.get(), packet_lengths, timeout,
1176 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this));
1177 }
1178 return RespondLater();
1179 }
1180
1181 void UsbIsochronousTransferFunction::OnCompleted(
1182 scoped_refptr<net::IOBuffer> data,
1183 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) {
1184 size_t length = std::accumulate(
1185 packets.begin(), packets.end(), 0,
1186 [](const size_t& a, const UsbDeviceHandle::IsochronousPacket& packet) {
1187 return a + packet.transferred_length;
1188 });
1189 scoped_ptr<char[]> buffer(new char[length]);
1190
1191 UsbTransferStatus status = device::USB_TRANSFER_COMPLETED;
1192 size_t buffer_offset = 0;
1193 size_t data_offset = 0;
1194 for (const auto& packet : packets) {
1195 // Capture the error status of the first unsuccessful packet.
1196 if (status == device::USB_TRANSFER_COMPLETED &&
1197 packet.status != device::USB_TRANSFER_COMPLETED) {
1198 status = packet.status;
1199 }
1200
1201 memcpy(&buffer[buffer_offset], data->data() + data_offset,
1202 packet.transferred_length);
1203 buffer_offset += packet.transferred_length;
1204 data_offset += packet.length;
1159 } 1205 }
1160 1206
1161 scoped_refptr<net::IOBuffer> buffer = 1207 scoped_ptr<base::DictionaryValue> transfer_info(new base::DictionaryValue());
1162 CreateBufferForTransfer(generic_transfer, direction, size); 1208 transfer_info->SetInteger(kResultCodeKey, status);
1163 if (!buffer.get()) { 1209 transfer_info->Set(kDataKey,
1164 return RespondNow(Error(kErrorMalformedParameters)); 1210 new base::BinaryValue(std::move(buffer), length));
1211 if (status == device::USB_TRANSFER_COMPLETED) {
1212 Respond(OneArgument(std::move(transfer_info)));
1213 } else {
1214 scoped_ptr<base::ListValue> error_args(new base::ListValue());
1215 error_args->Append(std::move(transfer_info));
1216 // Using ErrorWithArguments is discouraged but required to provide the
1217 // detailed transfer info as the transfer may have partially succeeded.
1218 Respond(ErrorWithArguments(std::move(error_args),
1219 ConvertTransferStatusToApi(status)));
1165 } 1220 }
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 } 1221 }
1178 1222
1179 UsbResetDeviceFunction::UsbResetDeviceFunction() { 1223 UsbResetDeviceFunction::UsbResetDeviceFunction() {
1180 } 1224 }
1181 1225
1182 UsbResetDeviceFunction::~UsbResetDeviceFunction() { 1226 UsbResetDeviceFunction::~UsbResetDeviceFunction() {
1183 } 1227 }
1184 1228
1185 ExtensionFunction::ResponseAction UsbResetDeviceFunction::Run() { 1229 ExtensionFunction::ResponseAction UsbResetDeviceFunction::Run() {
1186 parameters_ = ResetDevice::Params::Create(*args_); 1230 parameters_ = ResetDevice::Params::Create(*args_);
(...skipping 16 matching lines...) Expand all
1203 } else { 1247 } else {
1204 scoped_refptr<UsbDeviceHandle> device_handle = 1248 scoped_refptr<UsbDeviceHandle> device_handle =
1205 GetDeviceHandle(parameters_->handle); 1249 GetDeviceHandle(parameters_->handle);
1206 if (device_handle.get()) { 1250 if (device_handle.get()) {
1207 device_handle->Close(); 1251 device_handle->Close();
1208 } 1252 }
1209 ReleaseDeviceHandle(parameters_->handle); 1253 ReleaseDeviceHandle(parameters_->handle);
1210 1254
1211 scoped_ptr<base::ListValue> error_args(new base::ListValue()); 1255 scoped_ptr<base::ListValue> error_args(new base::ListValue());
1212 error_args->AppendBoolean(false); 1256 error_args->AppendBoolean(false);
1213 // Returning arguments with an error is wrong but we're stuck with it. 1257 // Using ErrorWithArguments is discouraged but required to maintain
1258 // compatibility with existing applications.
1214 Respond(ErrorWithArguments(std::move(error_args), kErrorResetDevice)); 1259 Respond(ErrorWithArguments(std::move(error_args), kErrorResetDevice));
1215 } 1260 }
1216 } 1261 }
1217 1262
1218 } // namespace extensions 1263 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/api/usb/usb_api.h ('k') | extensions/browser/api/usb/usb_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698