| 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 "extensions/browser/api/usb/usb_api.h" | 5 #include "extensions/browser/api/usb/usb_api.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <numeric> | 9 #include <numeric> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 namespace GetConfiguration = usb::GetConfiguration; | 44 namespace GetConfiguration = usb::GetConfiguration; |
| 45 namespace ListInterfaces = usb::ListInterfaces; | 45 namespace ListInterfaces = usb::ListInterfaces; |
| 46 namespace OpenDevice = usb::OpenDevice; | 46 namespace OpenDevice = usb::OpenDevice; |
| 47 namespace ReleaseInterface = usb::ReleaseInterface; | 47 namespace ReleaseInterface = usb::ReleaseInterface; |
| 48 namespace RequestAccess = usb::RequestAccess; | 48 namespace RequestAccess = usb::RequestAccess; |
| 49 namespace ResetDevice = usb::ResetDevice; | 49 namespace ResetDevice = usb::ResetDevice; |
| 50 namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting; | 50 namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting; |
| 51 | 51 |
| 52 using content::BrowserThread; | 52 using content::BrowserThread; |
| 53 using device::UsbConfigDescriptor; | 53 using device::UsbConfigDescriptor; |
| 54 using device::UsbControlTransferRecipient; |
| 55 using device::UsbControlTransferType; |
| 54 using device::UsbDevice; | 56 using device::UsbDevice; |
| 55 using device::UsbDeviceFilter; | 57 using device::UsbDeviceFilter; |
| 56 using device::UsbDeviceHandle; | 58 using device::UsbDeviceHandle; |
| 57 using device::UsbEndpointDescriptor; | 59 using device::UsbEndpointDescriptor; |
| 58 using device::UsbEndpointDirection; | |
| 59 using device::UsbInterfaceDescriptor; | 60 using device::UsbInterfaceDescriptor; |
| 60 using device::UsbService; | 61 using device::UsbService; |
| 61 using device::UsbSynchronizationType; | 62 using device::UsbSynchronizationType; |
| 63 using device::UsbTransferDirection; |
| 62 using device::UsbTransferStatus; | 64 using device::UsbTransferStatus; |
| 63 using device::UsbTransferType; | 65 using device::UsbTransferType; |
| 64 using device::UsbUsageType; | 66 using device::UsbUsageType; |
| 65 using std::string; | 67 using std::string; |
| 66 using std::vector; | 68 using std::vector; |
| 67 using usb::ConfigDescriptor; | 69 using usb::ConfigDescriptor; |
| 68 using usb::ControlTransferInfo; | 70 using usb::ControlTransferInfo; |
| 69 using usb::ConnectionHandle; | 71 using usb::ConnectionHandle; |
| 70 using usb::Device; | 72 using usb::Device; |
| 71 using usb::Direction; | 73 using usb::Direction; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 const char kErrorInvalidTimeout[] = | 122 const char kErrorInvalidTimeout[] = |
| 121 "Transfer timeout must be greater than or equal to 0."; | 123 "Transfer timeout must be greater than or equal to 0."; |
| 122 const char kErrorResetDevice[] = | 124 const char kErrorResetDevice[] = |
| 123 "Error resetting the device. The device has been closed."; | 125 "Error resetting the device. The device has been closed."; |
| 124 | 126 |
| 125 const size_t kMaxTransferLength = 100 * 1024 * 1024; | 127 const size_t kMaxTransferLength = 100 * 1024 * 1024; |
| 126 const int kMaxPackets = 4 * 1024 * 1024; | 128 const int kMaxPackets = 4 * 1024 * 1024; |
| 127 const int kMaxPacketLength = 64 * 1024; | 129 const int kMaxPacketLength = 64 * 1024; |
| 128 | 130 |
| 129 bool ConvertDirectionFromApi(const Direction& input, | 131 bool ConvertDirectionFromApi(const Direction& input, |
| 130 UsbEndpointDirection* output) { | 132 UsbTransferDirection* output) { |
| 131 switch (input) { | 133 switch (input) { |
| 132 case usb::DIRECTION_IN: | 134 case usb::DIRECTION_IN: |
| 133 *output = device::USB_DIRECTION_INBOUND; | 135 *output = UsbTransferDirection::INBOUND; |
| 134 return true; | 136 return true; |
| 135 case usb::DIRECTION_OUT: | 137 case usb::DIRECTION_OUT: |
| 136 *output = device::USB_DIRECTION_OUTBOUND; | 138 *output = UsbTransferDirection::OUTBOUND; |
| 137 return true; | 139 return true; |
| 138 default: | 140 default: |
| 139 NOTREACHED(); | 141 NOTREACHED(); |
| 140 return false; | 142 return false; |
| 141 } | 143 } |
| 142 } | 144 } |
| 143 | 145 |
| 144 bool ConvertRequestTypeFromApi(const RequestType& input, | 146 bool ConvertRequestTypeFromApi(const RequestType& input, |
| 145 UsbDeviceHandle::TransferRequestType* output) { | 147 UsbControlTransferType* output) { |
| 146 switch (input) { | 148 switch (input) { |
| 147 case usb::REQUEST_TYPE_STANDARD: | 149 case usb::REQUEST_TYPE_STANDARD: |
| 148 *output = UsbDeviceHandle::STANDARD; | 150 *output = UsbControlTransferType::STANDARD; |
| 149 return true; | 151 return true; |
| 150 case usb::REQUEST_TYPE_CLASS: | 152 case usb::REQUEST_TYPE_CLASS: |
| 151 *output = UsbDeviceHandle::CLASS; | 153 *output = UsbControlTransferType::CLASS; |
| 152 return true; | 154 return true; |
| 153 case usb::REQUEST_TYPE_VENDOR: | 155 case usb::REQUEST_TYPE_VENDOR: |
| 154 *output = UsbDeviceHandle::VENDOR; | 156 *output = UsbControlTransferType::VENDOR; |
| 155 return true; | 157 return true; |
| 156 case usb::REQUEST_TYPE_RESERVED: | 158 case usb::REQUEST_TYPE_RESERVED: |
| 157 *output = UsbDeviceHandle::RESERVED; | 159 *output = UsbControlTransferType::RESERVED; |
| 158 return true; | 160 return true; |
| 159 default: | 161 default: |
| 160 NOTREACHED(); | 162 NOTREACHED(); |
| 161 return false; | 163 return false; |
| 162 } | 164 } |
| 163 } | 165 } |
| 164 | 166 |
| 165 bool ConvertRecipientFromApi(const Recipient& input, | 167 bool ConvertRecipientFromApi(const Recipient& input, |
| 166 UsbDeviceHandle::TransferRecipient* output) { | 168 UsbControlTransferRecipient* output) { |
| 167 switch (input) { | 169 switch (input) { |
| 168 case usb::RECIPIENT_DEVICE: | 170 case usb::RECIPIENT_DEVICE: |
| 169 *output = UsbDeviceHandle::DEVICE; | 171 *output = UsbControlTransferRecipient::DEVICE; |
| 170 return true; | 172 return true; |
| 171 case usb::RECIPIENT_INTERFACE: | 173 case usb::RECIPIENT_INTERFACE: |
| 172 *output = UsbDeviceHandle::INTERFACE; | 174 *output = UsbControlTransferRecipient::INTERFACE; |
| 173 return true; | 175 return true; |
| 174 case usb::RECIPIENT_ENDPOINT: | 176 case usb::RECIPIENT_ENDPOINT: |
| 175 *output = UsbDeviceHandle::ENDPOINT; | 177 *output = UsbControlTransferRecipient::ENDPOINT; |
| 176 return true; | 178 return true; |
| 177 case usb::RECIPIENT_OTHER: | 179 case usb::RECIPIENT_OTHER: |
| 178 *output = UsbDeviceHandle::OTHER; | 180 *output = UsbControlTransferRecipient::OTHER; |
| 179 return true; | 181 return true; |
| 180 default: | 182 default: |
| 181 NOTREACHED(); | 183 NOTREACHED(); |
| 182 return false; | 184 return false; |
| 183 } | 185 } |
| 184 } | 186 } |
| 185 | 187 |
| 186 template <class T> | 188 template <class T> |
| 187 bool GetTransferSize(const T& input, size_t* output) { | 189 bool GetTransferSize(const T& input, size_t* output) { |
| 188 if (input.direction == usb::DIRECTION_IN) { | 190 if (input.direction == usb::DIRECTION_IN) { |
| 189 const int* length = input.length.get(); | 191 const int* length = input.length.get(); |
| 190 if (length && *length >= 0 && | 192 if (length && *length >= 0 && |
| 191 static_cast<size_t>(*length) < kMaxTransferLength) { | 193 static_cast<size_t>(*length) < kMaxTransferLength) { |
| 192 *output = *length; | 194 *output = *length; |
| 193 return true; | 195 return true; |
| 194 } | 196 } |
| 195 } else if (input.direction == usb::DIRECTION_OUT) { | 197 } else if (input.direction == usb::DIRECTION_OUT) { |
| 196 if (input.data.get()) { | 198 if (input.data.get()) { |
| 197 *output = input.data->size(); | 199 *output = input.data->size(); |
| 198 return true; | 200 return true; |
| 199 } | 201 } |
| 200 } | 202 } |
| 201 return false; | 203 return false; |
| 202 } | 204 } |
| 203 | 205 |
| 204 template <class T> | 206 template <class T> |
| 205 scoped_refptr<net::IOBuffer> CreateBufferForTransfer( | 207 scoped_refptr<net::IOBuffer> CreateBufferForTransfer( |
| 206 const T& input, | 208 const T& input, |
| 207 UsbEndpointDirection direction, | 209 UsbTransferDirection direction, |
| 208 size_t size) { | 210 size_t size) { |
| 209 if (size >= kMaxTransferLength) | 211 if (size >= kMaxTransferLength) |
| 210 return NULL; | 212 return NULL; |
| 211 | 213 |
| 212 // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This | 214 // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This |
| 213 // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer | 215 // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer |
| 214 // cannot represent a zero-length buffer, while an URB can. | 216 // cannot represent a zero-length buffer, while an URB can. |
| 215 scoped_refptr<net::IOBuffer> buffer = | 217 scoped_refptr<net::IOBuffer> buffer = |
| 216 new net::IOBuffer(std::max(static_cast<size_t>(1), size)); | 218 new net::IOBuffer(std::max(static_cast<size_t>(1), size)); |
| 217 | 219 |
| 218 if (direction == device::USB_DIRECTION_INBOUND) { | 220 if (direction == UsbTransferDirection::INBOUND) { |
| 219 return buffer; | 221 return buffer; |
| 220 } else if (direction == device::USB_DIRECTION_OUTBOUND) { | 222 } else if (direction == UsbTransferDirection::OUTBOUND) { |
| 221 if (input.data.get() && size <= input.data->size()) { | 223 if (input.data.get() && size <= input.data->size()) { |
| 222 memcpy(buffer->data(), input.data->data(), size); | 224 memcpy(buffer->data(), input.data->data(), size); |
| 223 return buffer; | 225 return buffer; |
| 224 } | 226 } |
| 225 } | 227 } |
| 226 NOTREACHED(); | 228 NOTREACHED(); |
| 227 return NULL; | 229 return NULL; |
| 228 } | 230 } |
| 229 | 231 |
| 230 const char* ConvertTransferStatusToApi(const UsbTransferStatus status) { | 232 const char* ConvertTransferStatusToApi(const UsbTransferStatus status) { |
| 231 switch (status) { | 233 switch (status) { |
| 232 case device::USB_TRANSFER_COMPLETED: | 234 case UsbTransferStatus::COMPLETED: |
| 233 return ""; | 235 return ""; |
| 234 case device::USB_TRANSFER_ERROR: | 236 case UsbTransferStatus::TRANSFER_ERROR: |
| 235 return kErrorGeneric; | 237 return kErrorGeneric; |
| 236 case device::USB_TRANSFER_TIMEOUT: | 238 case UsbTransferStatus::TIMEOUT: |
| 237 return kErrorTimeout; | 239 return kErrorTimeout; |
| 238 case device::USB_TRANSFER_CANCELLED: | 240 case UsbTransferStatus::CANCELLED: |
| 239 return kErrorCancelled; | 241 return kErrorCancelled; |
| 240 case device::USB_TRANSFER_STALLED: | 242 case UsbTransferStatus::STALLED: |
| 241 return kErrorStalled; | 243 return kErrorStalled; |
| 242 case device::USB_TRANSFER_DISCONNECT: | 244 case UsbTransferStatus::DISCONNECT: |
| 243 return kErrorDisconnect; | 245 return kErrorDisconnect; |
| 244 case device::USB_TRANSFER_OVERFLOW: | 246 case UsbTransferStatus::BABBLE: |
| 245 return kErrorOverflow; | 247 return kErrorOverflow; |
| 246 case device::USB_TRANSFER_LENGTH_SHORT: | 248 case UsbTransferStatus::SHORT_PACKET: |
| 247 return kErrorTransferLength; | 249 return kErrorTransferLength; |
| 248 default: | 250 default: |
| 249 NOTREACHED(); | 251 NOTREACHED(); |
| 250 return ""; | 252 return ""; |
| 251 } | 253 } |
| 252 } | 254 } |
| 253 | 255 |
| 254 std::unique_ptr<base::Value> PopulateConnectionHandle(int handle, | 256 std::unique_ptr<base::Value> PopulateConnectionHandle(int handle, |
| 255 int vendor_id, | 257 int vendor_id, |
| 256 int product_id) { | 258 int product_id) { |
| 257 ConnectionHandle result; | 259 ConnectionHandle result; |
| 258 result.handle = handle; | 260 result.handle = handle; |
| 259 result.vendor_id = vendor_id; | 261 result.vendor_id = vendor_id; |
| 260 result.product_id = product_id; | 262 result.product_id = product_id; |
| 261 return result.ToValue(); | 263 return result.ToValue(); |
| 262 } | 264 } |
| 263 | 265 |
| 264 TransferType ConvertTransferTypeToApi(const UsbTransferType& input) { | 266 TransferType ConvertTransferTypeToApi(const UsbTransferType& input) { |
| 265 switch (input) { | 267 switch (input) { |
| 266 case device::USB_TRANSFER_CONTROL: | 268 case UsbTransferType::CONTROL: |
| 267 return usb::TRANSFER_TYPE_CONTROL; | 269 return usb::TRANSFER_TYPE_CONTROL; |
| 268 case device::USB_TRANSFER_INTERRUPT: | 270 case UsbTransferType::INTERRUPT: |
| 269 return usb::TRANSFER_TYPE_INTERRUPT; | 271 return usb::TRANSFER_TYPE_INTERRUPT; |
| 270 case device::USB_TRANSFER_ISOCHRONOUS: | 272 case UsbTransferType::ISOCHRONOUS: |
| 271 return usb::TRANSFER_TYPE_ISOCHRONOUS; | 273 return usb::TRANSFER_TYPE_ISOCHRONOUS; |
| 272 case device::USB_TRANSFER_BULK: | 274 case UsbTransferType::BULK: |
| 273 return usb::TRANSFER_TYPE_BULK; | 275 return usb::TRANSFER_TYPE_BULK; |
| 274 default: | 276 default: |
| 275 NOTREACHED(); | 277 NOTREACHED(); |
| 276 return usb::TRANSFER_TYPE_NONE; | 278 return usb::TRANSFER_TYPE_NONE; |
| 277 } | 279 } |
| 278 } | 280 } |
| 279 | 281 |
| 280 Direction ConvertDirectionToApi(const UsbEndpointDirection& input) { | 282 Direction ConvertDirectionToApi(const UsbTransferDirection& input) { |
| 281 switch (input) { | 283 switch (input) { |
| 282 case device::USB_DIRECTION_INBOUND: | 284 case UsbTransferDirection::INBOUND: |
| 283 return usb::DIRECTION_IN; | 285 return usb::DIRECTION_IN; |
| 284 case device::USB_DIRECTION_OUTBOUND: | 286 case UsbTransferDirection::OUTBOUND: |
| 285 return usb::DIRECTION_OUT; | 287 return usb::DIRECTION_OUT; |
| 286 default: | 288 default: |
| 287 NOTREACHED(); | 289 NOTREACHED(); |
| 288 return usb::DIRECTION_NONE; | 290 return usb::DIRECTION_NONE; |
| 289 } | 291 } |
| 290 } | 292 } |
| 291 | 293 |
| 292 SynchronizationType ConvertSynchronizationTypeToApi( | 294 SynchronizationType ConvertSynchronizationTypeToApi( |
| 293 const UsbSynchronizationType& input) { | 295 const UsbSynchronizationType& input) { |
| 294 switch (input) { | 296 switch (input) { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 } | 458 } |
| 457 | 459 |
| 458 UsbTransferFunction::~UsbTransferFunction() { | 460 UsbTransferFunction::~UsbTransferFunction() { |
| 459 } | 461 } |
| 460 | 462 |
| 461 void UsbTransferFunction::OnCompleted(UsbTransferStatus status, | 463 void UsbTransferFunction::OnCompleted(UsbTransferStatus status, |
| 462 scoped_refptr<net::IOBuffer> data, | 464 scoped_refptr<net::IOBuffer> data, |
| 463 size_t length) { | 465 size_t length) { |
| 464 std::unique_ptr<base::DictionaryValue> transfer_info( | 466 std::unique_ptr<base::DictionaryValue> transfer_info( |
| 465 new base::DictionaryValue()); | 467 new base::DictionaryValue()); |
| 466 transfer_info->SetInteger(kResultCodeKey, status); | 468 transfer_info->SetInteger(kResultCodeKey, static_cast<int>(status)); |
| 467 | 469 |
| 468 if (data) { | 470 if (data) { |
| 469 transfer_info->Set( | 471 transfer_info->Set( |
| 470 kDataKey, base::Value::CreateWithCopiedBuffer(data->data(), length)); | 472 kDataKey, base::Value::CreateWithCopiedBuffer(data->data(), length)); |
| 471 } else { | 473 } else { |
| 472 transfer_info->Set(kDataKey, new base::Value(base::Value::Type::BINARY)); | 474 transfer_info->Set(kDataKey, new base::Value(base::Value::Type::BINARY)); |
| 473 } | 475 } |
| 474 | 476 |
| 475 if (status == device::USB_TRANSFER_COMPLETED) { | 477 if (status == UsbTransferStatus::COMPLETED) { |
| 476 Respond(OneArgument(std::move(transfer_info))); | 478 Respond(OneArgument(std::move(transfer_info))); |
| 477 } else { | 479 } else { |
| 478 std::unique_ptr<base::ListValue> error_args(new base::ListValue()); | 480 std::unique_ptr<base::ListValue> error_args(new base::ListValue()); |
| 479 error_args->Append(std::move(transfer_info)); | 481 error_args->Append(std::move(transfer_info)); |
| 480 // Using ErrorWithArguments is discouraged but required to provide the | 482 // Using ErrorWithArguments is discouraged but required to provide the |
| 481 // detailed transfer info as the transfer may have partially succeeded. | 483 // detailed transfer info as the transfer may have partially succeeded. |
| 482 Respond(ErrorWithArguments(std::move(error_args), | 484 Respond(ErrorWithArguments(std::move(error_args), |
| 483 ConvertTransferStatusToApi(status))); | 485 ConvertTransferStatusToApi(status))); |
| 484 } | 486 } |
| 485 } | 487 } |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 ControlTransfer::Params::Create(*args_); | 1011 ControlTransfer::Params::Create(*args_); |
| 1010 EXTENSION_FUNCTION_VALIDATE(parameters.get()); | 1012 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
| 1011 | 1013 |
| 1012 scoped_refptr<UsbDeviceHandle> device_handle = | 1014 scoped_refptr<UsbDeviceHandle> device_handle = |
| 1013 GetDeviceHandle(parameters->handle); | 1015 GetDeviceHandle(parameters->handle); |
| 1014 if (!device_handle.get()) { | 1016 if (!device_handle.get()) { |
| 1015 return RespondNow(Error(kErrorNoConnection)); | 1017 return RespondNow(Error(kErrorNoConnection)); |
| 1016 } | 1018 } |
| 1017 | 1019 |
| 1018 const ControlTransferInfo& transfer = parameters->transfer_info; | 1020 const ControlTransferInfo& transfer = parameters->transfer_info; |
| 1019 UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND; | 1021 UsbTransferDirection direction = UsbTransferDirection::INBOUND; |
| 1020 UsbDeviceHandle::TransferRequestType request_type; | 1022 UsbControlTransferType request_type; |
| 1021 UsbDeviceHandle::TransferRecipient recipient; | 1023 UsbControlTransferRecipient recipient; |
| 1022 size_t size = 0; | 1024 size_t size = 0; |
| 1023 | 1025 |
| 1024 if (!ConvertDirectionFromApi(transfer.direction, &direction)) { | 1026 if (!ConvertDirectionFromApi(transfer.direction, &direction)) { |
| 1025 return RespondNow(Error(kErrorConvertDirection)); | 1027 return RespondNow(Error(kErrorConvertDirection)); |
| 1026 } | 1028 } |
| 1027 | 1029 |
| 1028 if (!ConvertRequestTypeFromApi(transfer.request_type, &request_type)) { | 1030 if (!ConvertRequestTypeFromApi(transfer.request_type, &request_type)) { |
| 1029 return RespondNow(Error(kErrorConvertRequestType)); | 1031 return RespondNow(Error(kErrorConvertRequestType)); |
| 1030 } | 1032 } |
| 1031 | 1033 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1066 BulkTransfer::Params::Create(*args_); | 1068 BulkTransfer::Params::Create(*args_); |
| 1067 EXTENSION_FUNCTION_VALIDATE(parameters.get()); | 1069 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
| 1068 | 1070 |
| 1069 scoped_refptr<UsbDeviceHandle> device_handle = | 1071 scoped_refptr<UsbDeviceHandle> device_handle = |
| 1070 GetDeviceHandle(parameters->handle); | 1072 GetDeviceHandle(parameters->handle); |
| 1071 if (!device_handle.get()) { | 1073 if (!device_handle.get()) { |
| 1072 return RespondNow(Error(kErrorNoConnection)); | 1074 return RespondNow(Error(kErrorNoConnection)); |
| 1073 } | 1075 } |
| 1074 | 1076 |
| 1075 const GenericTransferInfo& transfer = parameters->transfer_info; | 1077 const GenericTransferInfo& transfer = parameters->transfer_info; |
| 1076 UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND; | 1078 UsbTransferDirection direction = UsbTransferDirection::INBOUND; |
| 1077 size_t size = 0; | 1079 size_t size = 0; |
| 1078 | 1080 |
| 1079 if (!ConvertDirectionFromApi(transfer.direction, &direction)) { | 1081 if (!ConvertDirectionFromApi(transfer.direction, &direction)) { |
| 1080 return RespondNow(Error(kErrorConvertDirection)); | 1082 return RespondNow(Error(kErrorConvertDirection)); |
| 1081 } | 1083 } |
| 1082 | 1084 |
| 1083 if (!GetTransferSize(transfer, &size)) { | 1085 if (!GetTransferSize(transfer, &size)) { |
| 1084 return RespondNow(Error(kErrorInvalidTransferLength)); | 1086 return RespondNow(Error(kErrorInvalidTransferLength)); |
| 1085 } | 1087 } |
| 1086 | 1088 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1112 InterruptTransfer::Params::Create(*args_); | 1114 InterruptTransfer::Params::Create(*args_); |
| 1113 EXTENSION_FUNCTION_VALIDATE(parameters.get()); | 1115 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
| 1114 | 1116 |
| 1115 scoped_refptr<UsbDeviceHandle> device_handle = | 1117 scoped_refptr<UsbDeviceHandle> device_handle = |
| 1116 GetDeviceHandle(parameters->handle); | 1118 GetDeviceHandle(parameters->handle); |
| 1117 if (!device_handle.get()) { | 1119 if (!device_handle.get()) { |
| 1118 return RespondNow(Error(kErrorNoConnection)); | 1120 return RespondNow(Error(kErrorNoConnection)); |
| 1119 } | 1121 } |
| 1120 | 1122 |
| 1121 const GenericTransferInfo& transfer = parameters->transfer_info; | 1123 const GenericTransferInfo& transfer = parameters->transfer_info; |
| 1122 UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND; | 1124 UsbTransferDirection direction = UsbTransferDirection::INBOUND; |
| 1123 size_t size = 0; | 1125 size_t size = 0; |
| 1124 | 1126 |
| 1125 if (!ConvertDirectionFromApi(transfer.direction, &direction)) { | 1127 if (!ConvertDirectionFromApi(transfer.direction, &direction)) { |
| 1126 return RespondNow(Error(kErrorConvertDirection)); | 1128 return RespondNow(Error(kErrorConvertDirection)); |
| 1127 } | 1129 } |
| 1128 | 1130 |
| 1129 if (!GetTransferSize(transfer, &size)) { | 1131 if (!GetTransferSize(transfer, &size)) { |
| 1130 return RespondNow(Error(kErrorInvalidTransferLength)); | 1132 return RespondNow(Error(kErrorInvalidTransferLength)); |
| 1131 } | 1133 } |
| 1132 | 1134 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1160 | 1162 |
| 1161 scoped_refptr<UsbDeviceHandle> device_handle = | 1163 scoped_refptr<UsbDeviceHandle> device_handle = |
| 1162 GetDeviceHandle(parameters->handle); | 1164 GetDeviceHandle(parameters->handle); |
| 1163 if (!device_handle.get()) { | 1165 if (!device_handle.get()) { |
| 1164 return RespondNow(Error(kErrorNoConnection)); | 1166 return RespondNow(Error(kErrorNoConnection)); |
| 1165 } | 1167 } |
| 1166 | 1168 |
| 1167 const IsochronousTransferInfo& transfer = parameters->transfer_info; | 1169 const IsochronousTransferInfo& transfer = parameters->transfer_info; |
| 1168 const GenericTransferInfo& generic_transfer = transfer.transfer_info; | 1170 const GenericTransferInfo& generic_transfer = transfer.transfer_info; |
| 1169 size_t size = 0; | 1171 size_t size = 0; |
| 1170 UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND; | 1172 UsbTransferDirection direction = UsbTransferDirection::INBOUND; |
| 1171 | 1173 |
| 1172 if (!ConvertDirectionFromApi(generic_transfer.direction, &direction)) | 1174 if (!ConvertDirectionFromApi(generic_transfer.direction, &direction)) |
| 1173 return RespondNow(Error(kErrorConvertDirection)); | 1175 return RespondNow(Error(kErrorConvertDirection)); |
| 1174 | 1176 |
| 1175 if (!GetTransferSize(generic_transfer, &size)) | 1177 if (!GetTransferSize(generic_transfer, &size)) |
| 1176 return RespondNow(Error(kErrorInvalidTransferLength)); | 1178 return RespondNow(Error(kErrorInvalidTransferLength)); |
| 1177 | 1179 |
| 1178 if (transfer.packets < 0 || transfer.packets >= kMaxPackets) | 1180 if (transfer.packets < 0 || transfer.packets >= kMaxPackets) |
| 1179 return RespondNow(Error(kErrorInvalidNumberOfPackets)); | 1181 return RespondNow(Error(kErrorInvalidNumberOfPackets)); |
| 1180 size_t packets = transfer.packets; | 1182 size_t packets = transfer.packets; |
| 1181 | 1183 |
| 1182 if (transfer.packet_length < 0 || | 1184 if (transfer.packet_length < 0 || |
| 1183 transfer.packet_length >= kMaxPacketLength) { | 1185 transfer.packet_length >= kMaxPacketLength) { |
| 1184 return RespondNow(Error(kErrorInvalidPacketLength)); | 1186 return RespondNow(Error(kErrorInvalidPacketLength)); |
| 1185 } | 1187 } |
| 1186 | 1188 |
| 1187 size_t total_length = packets * transfer.packet_length; | 1189 size_t total_length = packets * transfer.packet_length; |
| 1188 if (packets > size || total_length > size) | 1190 if (packets > size || total_length > size) |
| 1189 return RespondNow(Error(kErrorTransferLength)); | 1191 return RespondNow(Error(kErrorTransferLength)); |
| 1190 std::vector<uint32_t> packet_lengths(packets, transfer.packet_length); | 1192 std::vector<uint32_t> packet_lengths(packets, transfer.packet_length); |
| 1191 | 1193 |
| 1192 int timeout = generic_transfer.timeout ? *generic_transfer.timeout : 0; | 1194 int timeout = generic_transfer.timeout ? *generic_transfer.timeout : 0; |
| 1193 if (timeout < 0) | 1195 if (timeout < 0) |
| 1194 return RespondNow(Error(kErrorInvalidTimeout)); | 1196 return RespondNow(Error(kErrorInvalidTimeout)); |
| 1195 | 1197 |
| 1196 if (direction == device::USB_DIRECTION_INBOUND) { | 1198 if (direction == UsbTransferDirection::INBOUND) { |
| 1197 device_handle->IsochronousTransferIn( | 1199 device_handle->IsochronousTransferIn( |
| 1198 generic_transfer.endpoint, packet_lengths, timeout, | 1200 generic_transfer.endpoint, packet_lengths, timeout, |
| 1199 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this)); | 1201 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this)); |
| 1200 } else { | 1202 } else { |
| 1201 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer( | 1203 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer( |
| 1202 generic_transfer, direction, transfer.packets * transfer.packet_length); | 1204 generic_transfer, direction, transfer.packets * transfer.packet_length); |
| 1203 if (!buffer.get()) | 1205 if (!buffer.get()) |
| 1204 return RespondNow(Error(kErrorMalformedParameters)); | 1206 return RespondNow(Error(kErrorMalformedParameters)); |
| 1205 | 1207 |
| 1206 device_handle->IsochronousTransferOut( | 1208 device_handle->IsochronousTransferOut( |
| 1207 generic_transfer.endpoint, buffer.get(), packet_lengths, timeout, | 1209 generic_transfer.endpoint, buffer.get(), packet_lengths, timeout, |
| 1208 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this)); | 1210 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this)); |
| 1209 } | 1211 } |
| 1210 return RespondLater(); | 1212 return RespondLater(); |
| 1211 } | 1213 } |
| 1212 | 1214 |
| 1213 void UsbIsochronousTransferFunction::OnCompleted( | 1215 void UsbIsochronousTransferFunction::OnCompleted( |
| 1214 scoped_refptr<net::IOBuffer> data, | 1216 scoped_refptr<net::IOBuffer> data, |
| 1215 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { | 1217 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { |
| 1216 size_t length = std::accumulate( | 1218 size_t length = std::accumulate( |
| 1217 packets.begin(), packets.end(), 0, | 1219 packets.begin(), packets.end(), 0, |
| 1218 [](const size_t& a, const UsbDeviceHandle::IsochronousPacket& packet) { | 1220 [](const size_t& a, const UsbDeviceHandle::IsochronousPacket& packet) { |
| 1219 return a + packet.transferred_length; | 1221 return a + packet.transferred_length; |
| 1220 }); | 1222 }); |
| 1221 std::vector<char> buffer; | 1223 std::vector<char> buffer; |
| 1222 buffer.reserve(length); | 1224 buffer.reserve(length); |
| 1223 | 1225 |
| 1224 UsbTransferStatus status = device::USB_TRANSFER_COMPLETED; | 1226 UsbTransferStatus status = UsbTransferStatus::COMPLETED; |
| 1225 const char* data_ptr = data ? data->data() : nullptr; | 1227 const char* data_ptr = data ? data->data() : nullptr; |
| 1226 for (const auto& packet : packets) { | 1228 for (const auto& packet : packets) { |
| 1227 // Capture the error status of the first unsuccessful packet. | 1229 // Capture the error status of the first unsuccessful packet. |
| 1228 if (status == device::USB_TRANSFER_COMPLETED && | 1230 if (status == UsbTransferStatus::COMPLETED && |
| 1229 packet.status != device::USB_TRANSFER_COMPLETED) { | 1231 packet.status != UsbTransferStatus::COMPLETED) { |
| 1230 status = packet.status; | 1232 status = packet.status; |
| 1231 } | 1233 } |
| 1232 | 1234 |
| 1233 if (data) { | 1235 if (data) { |
| 1234 buffer.insert(buffer.end(), data_ptr, | 1236 buffer.insert(buffer.end(), data_ptr, |
| 1235 data_ptr + packet.transferred_length); | 1237 data_ptr + packet.transferred_length); |
| 1236 data_ptr += packet.length; | 1238 data_ptr += packet.length; |
| 1237 } | 1239 } |
| 1238 } | 1240 } |
| 1239 | 1241 |
| 1240 std::unique_ptr<base::DictionaryValue> transfer_info( | 1242 std::unique_ptr<base::DictionaryValue> transfer_info( |
| 1241 new base::DictionaryValue()); | 1243 new base::DictionaryValue()); |
| 1242 transfer_info->SetInteger(kResultCodeKey, status); | 1244 transfer_info->SetInteger(kResultCodeKey, static_cast<int>(status)); |
| 1243 transfer_info->Set(kDataKey, new base::Value(std::move(buffer))); | 1245 transfer_info->Set(kDataKey, new base::Value(std::move(buffer))); |
| 1244 if (status == device::USB_TRANSFER_COMPLETED) { | 1246 if (status == UsbTransferStatus::COMPLETED) { |
| 1245 Respond(OneArgument(std::move(transfer_info))); | 1247 Respond(OneArgument(std::move(transfer_info))); |
| 1246 } else { | 1248 } else { |
| 1247 std::unique_ptr<base::ListValue> error_args(new base::ListValue()); | 1249 std::unique_ptr<base::ListValue> error_args(new base::ListValue()); |
| 1248 error_args->Append(std::move(transfer_info)); | 1250 error_args->Append(std::move(transfer_info)); |
| 1249 // Using ErrorWithArguments is discouraged but required to provide the | 1251 // Using ErrorWithArguments is discouraged but required to provide the |
| 1250 // detailed transfer info as the transfer may have partially succeeded. | 1252 // detailed transfer info as the transfer may have partially succeeded. |
| 1251 Respond(ErrorWithArguments(std::move(error_args), | 1253 Respond(ErrorWithArguments(std::move(error_args), |
| 1252 ConvertTransferStatusToApi(status))); | 1254 ConvertTransferStatusToApi(status))); |
| 1253 } | 1255 } |
| 1254 } | 1256 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1287 | 1289 |
| 1288 std::unique_ptr<base::ListValue> error_args(new base::ListValue()); | 1290 std::unique_ptr<base::ListValue> error_args(new base::ListValue()); |
| 1289 error_args->AppendBoolean(false); | 1291 error_args->AppendBoolean(false); |
| 1290 // Using ErrorWithArguments is discouraged but required to maintain | 1292 // Using ErrorWithArguments is discouraged but required to maintain |
| 1291 // compatibility with existing applications. | 1293 // compatibility with existing applications. |
| 1292 Respond(ErrorWithArguments(std::move(error_args), kErrorResetDevice)); | 1294 Respond(ErrorWithArguments(std::move(error_args), kErrorResetDevice)); |
| 1293 } | 1295 } |
| 1294 } | 1296 } |
| 1295 | 1297 |
| 1296 } // namespace extensions | 1298 } // namespace extensions |
| OLD | NEW |