Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/usb/usb_api.h" | 5 #include "chrome/browser/extensions/api/usb/usb_api.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "chrome/browser/extensions/api/usb/usb_device_resource.h" | 11 #include "chrome/browser/extensions/api/usb/usb_device_resource.h" |
| 12 #include "chrome/browser/extensions/extension_system.h" | 12 #include "chrome/browser/extensions/extension_system.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/usb/usb_service.h" | 14 #include "chrome/browser/usb/usb_service.h" |
| 15 #include "chrome/browser/usb/usb_service_factory.h" | 15 #include "chrome/browser/usb/usb_service_factory.h" |
| 16 #include "chrome/common/extensions/api/usb.h" | 16 #include "chrome/common/extensions/api/usb.h" |
| 17 #include "chrome/common/extensions/permissions/usb_device_permission.h" | 17 #include "chrome/common/extensions/permissions/usb_device_permission.h" |
| 18 | 18 |
| 19 namespace BulkTransfer = extensions::api::usb::BulkTransfer; | 19 namespace BulkTransfer = extensions::api::usb::BulkTransfer; |
| 20 namespace ClaimInterface = extensions::api::usb::ClaimInterface; | 20 namespace ClaimInterface = extensions::api::usb::ClaimInterface; |
| 21 namespace ListInterfaces = extensions::api::usb::ListInterfaces; | |
| 21 namespace CloseDevice = extensions::api::usb::CloseDevice; | 22 namespace CloseDevice = extensions::api::usb::CloseDevice; |
| 22 namespace ControlTransfer = extensions::api::usb::ControlTransfer; | 23 namespace ControlTransfer = extensions::api::usb::ControlTransfer; |
| 23 namespace FindDevices = extensions::api::usb::FindDevices; | 24 namespace FindDevices = extensions::api::usb::FindDevices; |
| 24 namespace InterruptTransfer = extensions::api::usb::InterruptTransfer; | 25 namespace InterruptTransfer = extensions::api::usb::InterruptTransfer; |
| 25 namespace IsochronousTransfer = extensions::api::usb::IsochronousTransfer; | 26 namespace IsochronousTransfer = extensions::api::usb::IsochronousTransfer; |
| 26 namespace ReleaseInterface = extensions::api::usb::ReleaseInterface; | 27 namespace ReleaseInterface = extensions::api::usb::ReleaseInterface; |
| 27 namespace ResetDevice = extensions::api::usb::ResetDevice; | 28 namespace ResetDevice = extensions::api::usb::ResetDevice; |
| 28 namespace SetInterfaceAlternateSetting = | 29 namespace SetInterfaceAlternateSetting = |
| 29 extensions::api::usb::SetInterfaceAlternateSetting; | 30 extensions::api::usb::SetInterfaceAlternateSetting; |
| 30 namespace usb = extensions::api::usb; | 31 namespace usb = extensions::api::usb; |
| 31 | 32 |
| 32 using std::string; | 33 using std::string; |
| 33 using std::vector; | 34 using std::vector; |
| 34 using usb::ControlTransferInfo; | 35 using usb::ControlTransferInfo; |
| 35 using usb::Device; | 36 using usb::Device; |
| 36 using usb::Direction; | 37 using usb::Direction; |
| 38 using usb::EndpointDescriptor; | |
| 37 using usb::GenericTransferInfo; | 39 using usb::GenericTransferInfo; |
| 40 using usb::InterfaceDescriptor; | |
| 38 using usb::IsochronousTransferInfo; | 41 using usb::IsochronousTransferInfo; |
| 39 using usb::Recipient; | 42 using usb::Recipient; |
| 40 using usb::RequestType; | 43 using usb::RequestType; |
| 44 using usb::SynchronizationType; | |
| 45 using usb::TransferType; | |
| 46 using usb::UsageType; | |
| 41 | 47 |
| 42 namespace { | 48 namespace { |
| 43 | 49 |
| 44 static const char* kDataKey = "data"; | 50 static const char* kDataKey = "data"; |
| 45 static const char* kResultCodeKey = "resultCode"; | 51 static const char* kResultCodeKey = "resultCode"; |
| 46 | 52 |
| 47 static const char* kErrorCancelled = "Transfer was cancelled."; | 53 static const char* kErrorCancelled = "Transfer was cancelled."; |
| 48 static const char* kErrorDisconnect = "Device disconnected."; | 54 static const char* kErrorDisconnect = "Device disconnected."; |
| 49 static const char* kErrorGeneric = "Transfer failed."; | 55 static const char* kErrorGeneric = "Transfer failed."; |
| 50 static const char* kErrorOverflow = "Inbound transfer overflow."; | 56 static const char* kErrorOverflow = "Inbound transfer overflow."; |
| 51 static const char* kErrorStalled = "Transfer stalled."; | 57 static const char* kErrorStalled = "Transfer stalled."; |
| 52 static const char* kErrorTimeout = "Transfer timed out."; | 58 static const char* kErrorTimeout = "Transfer timed out."; |
| 53 static const char* kErrorTransferLength = "Transfer length is insufficient."; | 59 static const char* kErrorTransferLength = "Transfer length is insufficient."; |
| 54 | 60 |
| 61 static const char* kErrorCannotListInterfaces = "Error listing interfaces."; | |
| 55 static const char* kErrorCannotClaimInterface = "Error claiming interface."; | 62 static const char* kErrorCannotClaimInterface = "Error claiming interface."; |
| 56 static const char* kErrorCannotReleaseInterface = "Error releasing interface."; | 63 static const char* kErrorCannotReleaseInterface = "Error releasing interface."; |
| 57 static const char* kErrorCannotSetInterfaceAlternateSetting = | 64 static const char* kErrorCannotSetInterfaceAlternateSetting = |
| 58 "Error setting alternate interface setting."; | 65 "Error setting alternate interface setting."; |
| 59 static const char* kErrorConvertDirection = "Invalid transfer direction."; | 66 static const char* kErrorConvertDirection = "Invalid transfer direction."; |
| 60 static const char* kErrorConvertRecipient = "Invalid transfer recipient."; | 67 static const char* kErrorConvertRecipient = "Invalid transfer recipient."; |
| 61 static const char* kErrorConvertRequestType = "Invalid request type."; | 68 static const char* kErrorConvertRequestType = "Invalid request type."; |
| 69 static const char* kErrorConvertSynchronizationType = | |
| 70 "Invalid synchronization type"; | |
| 71 static const char* kErrorConvertTransferType = "Invalid endpoint type."; | |
| 72 static const char* kErrorConvertUsageType = "Invalid usage type."; | |
| 62 static const char* kErrorMalformedParameters = "Error parsing parameters."; | 73 static const char* kErrorMalformedParameters = "Error parsing parameters."; |
| 63 static const char* kErrorNoDevice = "No such device."; | 74 static const char* kErrorNoDevice = "No such device."; |
| 64 static const char* kErrorPermissionDenied = | 75 static const char* kErrorPermissionDenied = |
| 65 "Permission to access device was denied"; | 76 "Permission to access device was denied"; |
| 66 static const char* kErrorInvalidTransferLength = "Transfer length must be a " | 77 static const char* kErrorInvalidTransferLength = "Transfer length must be a " |
| 67 "positive number less than 104,857,600."; | 78 "positive number less than 104,857,600."; |
| 68 static const char* kErrorInvalidNumberOfPackets = "Number of packets must be a " | 79 static const char* kErrorInvalidNumberOfPackets = "Number of packets must be a " |
| 69 "positive number less than 4,194,304."; | 80 "positive number less than 4,194,304."; |
| 70 static const char* kErrorInvalidPacketLength = "Packet length must be a " | 81 static const char* kErrorInvalidPacketLength = "Packet length must be a " |
| 71 "positive number less than 65,536."; | 82 "positive number less than 65,536."; |
| 72 static const char* kErrorResetDevice = | 83 static const char* kErrorResetDevice = |
| 73 "Error resetting the device. The device has been closed."; | 84 "Error resetting the device. The device has been closed."; |
| 74 | 85 |
| 75 static const size_t kMaxTransferLength = 100 * 1024 * 1024; | 86 static const size_t kMaxTransferLength = 100 * 1024 * 1024; |
| 76 static const int kMaxPackets = 4 * 1024 * 1024; | 87 static const int kMaxPackets = 4 * 1024 * 1024; |
| 77 static const int kMaxPacketLength = 64 * 1024; | 88 static const int kMaxPacketLength = 64 * 1024; |
| 78 | 89 |
| 79 static UsbDevice* device_for_test_ = NULL; | 90 static UsbDevice* device_for_test_ = NULL; |
| 80 | 91 |
| 92 static bool ConvertDirectionToApi(const UsbEndpointDirection& input, | |
| 93 Direction* output) { | |
| 94 switch (input) { | |
| 95 case USB_DIRECTION_INBOUND: | |
| 96 *output = usb::DIRECTION_IN; | |
| 97 return true; | |
| 98 case USB_DIRECTION_OUTBOUND: | |
| 99 *output = usb::DIRECTION_OUT; | |
| 100 return true; | |
| 101 default: | |
| 102 NOTREACHED(); | |
| 103 return false; | |
| 104 } | |
| 105 } | |
| 106 | |
| 107 static bool ConvertSynchronizationTypeToApi( | |
| 108 const UsbSynchronizationType& input, | |
| 109 extensions::api::usb::SynchronizationType* output) { | |
| 110 switch (input) { | |
| 111 case USB_SYNCHRONIZATION_NONE: | |
| 112 *output = usb::SYNCHRONIZATION_TYPE_NONE; | |
| 113 return true; | |
| 114 case USB_SYNCHRONIZATION_ASYNCHRONOUS: | |
| 115 *output = usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS; | |
| 116 return true; | |
| 117 case USB_SYNCHRONIZATION_ADAPTIVE: | |
| 118 *output = usb::SYNCHRONIZATION_TYPE_ADAPTIVE; | |
| 119 return true; | |
| 120 case USB_SYNCHRONIZATION_SYNCHRONOUS: | |
| 121 *output = usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS; | |
| 122 return true; | |
| 123 default: | |
| 124 NOTREACHED(); | |
| 125 return false; | |
| 126 } | |
| 127 } | |
| 128 | |
| 129 static bool ConvertTransferTypeToApi( | |
| 130 const UsbTransferType& input, | |
| 131 extensions::api::usb::TransferType* output) { | |
| 132 switch (input) { | |
| 133 case USB_TRANSFER_CONTROL: | |
| 134 *output = usb::TRANSFER_TYPE_CONTROL; | |
| 135 return true; | |
| 136 case USB_TRANSFER_INTERRUPT: | |
| 137 *output = usb::TRANSFER_TYPE_INTERRUPT; | |
| 138 return true; | |
| 139 case USB_TRANSFER_ISOCHRONOUS: | |
| 140 *output = usb::TRANSFER_TYPE_ISOCHRONOUS; | |
| 141 return true; | |
| 142 case USB_TRANSFER_BULK: | |
| 143 *output = usb::TRANSFER_TYPE_BULK; | |
| 144 return true; | |
| 145 default: | |
| 146 NOTREACHED(); | |
| 147 return false; | |
| 148 } | |
| 149 } | |
| 150 | |
| 151 static bool ConvertUsageTypeToApi(const UsbUsageType& input, | |
| 152 extensions::api::usb::UsageType* output) { | |
| 153 switch (input) { | |
| 154 case USB_USAGE_DATA: | |
| 155 *output = usb::USAGE_TYPE_DATA; | |
| 156 return true; | |
| 157 case USB_USAGE_FEEDBACK: | |
| 158 *output = usb::USAGE_TYPE_FEEDBACK; | |
| 159 return true; | |
| 160 case USB_USAGE_EXPLICIT_FEEDBACK: | |
| 161 *output = usb::USAGE_TYPE_EXPLICITFEEDBACK; | |
| 162 return true; | |
| 163 default: | |
| 164 NOTREACHED(); | |
| 165 return false; | |
| 166 } | |
| 167 } | |
| 168 | |
| 81 static bool ConvertDirection(const Direction& input, | 169 static bool ConvertDirection(const Direction& input, |
| 82 UsbDevice::TransferDirection* output) { | 170 UsbEndpointDirection* output) { |
| 83 switch (input) { | 171 switch (input) { |
| 84 case usb::DIRECTION_IN: | 172 case usb::DIRECTION_IN: |
| 85 *output = UsbDevice::INBOUND; | 173 *output = USB_DIRECTION_INBOUND; |
| 86 return true; | 174 return true; |
| 87 case usb::DIRECTION_OUT: | 175 case usb::DIRECTION_OUT: |
| 88 *output = UsbDevice::OUTBOUND; | 176 *output = USB_DIRECTION_OUTBOUND; |
| 89 return true; | 177 return true; |
| 90 default: | 178 default: |
| 179 NOTREACHED(); | |
| 91 return false; | 180 return false; |
| 92 } | 181 } |
| 93 NOTREACHED(); | |
| 94 return false; | |
| 95 } | 182 } |
| 96 | 183 |
| 97 static bool ConvertRequestType(const RequestType& input, | 184 static bool ConvertRequestType(const RequestType& input, |
| 98 UsbDevice::TransferRequestType* output) { | 185 UsbDevice::TransferRequestType* output) { |
| 99 switch (input) { | 186 switch (input) { |
| 100 case usb::REQUEST_TYPE_STANDARD: | 187 case usb::REQUEST_TYPE_STANDARD: |
| 101 *output = UsbDevice::STANDARD; | 188 *output = UsbDevice::STANDARD; |
| 102 return true; | 189 return true; |
| 103 case usb::REQUEST_TYPE_CLASS: | 190 case usb::REQUEST_TYPE_CLASS: |
| 104 *output = UsbDevice::CLASS; | 191 *output = UsbDevice::CLASS; |
| 105 return true; | 192 return true; |
| 106 case usb::REQUEST_TYPE_VENDOR: | 193 case usb::REQUEST_TYPE_VENDOR: |
| 107 *output = UsbDevice::VENDOR; | 194 *output = UsbDevice::VENDOR; |
| 108 return true; | 195 return true; |
| 109 case usb::REQUEST_TYPE_RESERVED: | 196 case usb::REQUEST_TYPE_RESERVED: |
| 110 *output = UsbDevice::RESERVED; | 197 *output = UsbDevice::RESERVED; |
| 111 return true; | 198 return true; |
| 112 default: | 199 default: |
| 200 NOTREACHED(); | |
| 113 return false; | 201 return false; |
| 114 } | 202 } |
| 115 NOTREACHED(); | |
| 116 return false; | |
| 117 } | 203 } |
| 118 | 204 |
| 119 static bool ConvertRecipient(const Recipient& input, | 205 static bool ConvertRecipient(const Recipient& input, |
| 120 UsbDevice::TransferRecipient* output) { | 206 UsbDevice::TransferRecipient* output) { |
| 121 switch (input) { | 207 switch (input) { |
| 122 case usb::RECIPIENT_DEVICE: | 208 case usb::RECIPIENT_DEVICE: |
| 123 *output = UsbDevice::DEVICE; | 209 *output = UsbDevice::DEVICE; |
| 124 return true; | 210 return true; |
| 125 case usb::RECIPIENT_INTERFACE: | 211 case usb::RECIPIENT_INTERFACE: |
| 126 *output = UsbDevice::INTERFACE; | 212 *output = UsbDevice::INTERFACE; |
| 127 return true; | 213 return true; |
| 128 case usb::RECIPIENT_ENDPOINT: | 214 case usb::RECIPIENT_ENDPOINT: |
| 129 *output = UsbDevice::ENDPOINT; | 215 *output = UsbDevice::ENDPOINT; |
| 130 return true; | 216 return true; |
| 131 case usb::RECIPIENT_OTHER: | 217 case usb::RECIPIENT_OTHER: |
| 132 *output = UsbDevice::OTHER; | 218 *output = UsbDevice::OTHER; |
| 133 return true; | 219 return true; |
| 134 default: | 220 default: |
| 221 NOTREACHED(); | |
| 135 return false; | 222 return false; |
| 136 } | 223 } |
| 137 NOTREACHED(); | |
| 138 return false; | |
| 139 } | 224 } |
| 140 | 225 |
| 141 template<class T> | 226 template<class T> |
| 142 static bool GetTransferSize(const T& input, size_t* output) { | 227 static bool GetTransferSize(const T& input, size_t* output) { |
| 143 if (input.direction == usb::DIRECTION_IN) { | 228 if (input.direction == usb::DIRECTION_IN) { |
| 144 const int* length = input.length.get(); | 229 const int* length = input.length.get(); |
| 145 if (length && *length >= 0 && | 230 if (length && *length >= 0 && |
| 146 static_cast<size_t>(*length) < kMaxTransferLength) { | 231 static_cast<size_t>(*length) < kMaxTransferLength) { |
| 147 *output = *length; | 232 *output = *length; |
| 148 return true; | 233 return true; |
| 149 } | 234 } |
| 150 } else if (input.direction == usb::DIRECTION_OUT) { | 235 } else if (input.direction == usb::DIRECTION_OUT) { |
| 151 if (input.data.get()) { | 236 if (input.data.get()) { |
| 152 *output = input.data->size(); | 237 *output = input.data->size(); |
| 153 return true; | 238 return true; |
| 154 } | 239 } |
| 155 } | 240 } |
| 156 return false; | 241 return false; |
| 157 } | 242 } |
| 158 | 243 |
| 159 template<class T> | 244 template<class T> |
| 160 static scoped_refptr<net::IOBuffer> CreateBufferForTransfer( | 245 static scoped_refptr<net::IOBuffer> CreateBufferForTransfer( |
| 161 const T& input, UsbDevice::TransferDirection direction, size_t size) { | 246 const T& input, UsbEndpointDirection direction, size_t size) { |
| 162 | 247 |
| 163 if (size >= kMaxTransferLength) | 248 if (size >= kMaxTransferLength) |
| 164 return NULL; | 249 return NULL; |
| 165 | 250 |
| 166 // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This | 251 // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This |
| 167 // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer | 252 // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer |
| 168 // cannot represent a zero-length buffer, while an URB can. | 253 // cannot represent a zero-length buffer, while an URB can. |
| 169 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(std::max( | 254 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(std::max( |
| 170 static_cast<size_t>(1), size)); | 255 static_cast<size_t>(1), size)); |
| 171 | 256 |
| 172 if (direction == UsbDevice::INBOUND) { | 257 if (direction == USB_DIRECTION_INBOUND) { |
| 173 return buffer; | 258 return buffer; |
| 174 } else if (direction == UsbDevice::OUTBOUND) { | 259 } else if (direction == USB_DIRECTION_OUTBOUND) { |
| 175 if (input.data.get() && size <= input.data->size()) { | 260 if (input.data.get() && size <= input.data->size()) { |
| 176 memcpy(buffer->data(), input.data->data(), size); | 261 memcpy(buffer->data(), input.data->data(), size); |
| 177 return buffer; | 262 return buffer; |
| 178 } | 263 } |
| 179 } | 264 } |
| 180 NOTREACHED(); | 265 NOTREACHED(); |
| 181 return NULL; | 266 return NULL; |
| 182 } | 267 } |
| 183 | 268 |
| 184 static const char* ConvertTransferStatusToErrorString( | 269 static const char* ConvertTransferStatusToErrorString( |
| 185 const UsbTransferStatus status) { | 270 const UsbTransferStatus status) { |
| 186 switch (status) { | 271 switch (status) { |
| 187 case USB_TRANSFER_COMPLETED: | 272 case USB_TRANSFER_COMPLETED: |
| 188 return ""; | 273 return ""; |
| 189 case USB_TRANSFER_ERROR: | 274 case USB_TRANSFER_ERROR: |
| 190 return kErrorGeneric; | 275 return kErrorGeneric; |
| 191 case USB_TRANSFER_TIMEOUT: | 276 case USB_TRANSFER_TIMEOUT: |
| 192 return kErrorTimeout; | 277 return kErrorTimeout; |
| 193 case USB_TRANSFER_CANCELLED: | 278 case USB_TRANSFER_CANCELLED: |
| 194 return kErrorCancelled; | 279 return kErrorCancelled; |
| 195 case USB_TRANSFER_STALLED: | 280 case USB_TRANSFER_STALLED: |
| 196 return kErrorStalled; | 281 return kErrorStalled; |
| 197 case USB_TRANSFER_DISCONNECT: | 282 case USB_TRANSFER_DISCONNECT: |
| 198 return kErrorDisconnect; | 283 return kErrorDisconnect; |
| 199 case USB_TRANSFER_OVERFLOW: | 284 case USB_TRANSFER_OVERFLOW: |
| 200 return kErrorOverflow; | 285 return kErrorOverflow; |
| 201 case USB_TRANSFER_LENGTH_SHORT: | 286 case USB_TRANSFER_LENGTH_SHORT: |
| 202 return kErrorTransferLength; | 287 return kErrorTransferLength; |
| 288 default: | |
| 289 NOTREACHED(); | |
| 290 return ""; | |
| 203 } | 291 } |
| 204 | |
| 205 NOTREACHED(); | |
| 206 return ""; | |
| 207 } | 292 } |
| 208 | 293 |
| 209 static base::DictionaryValue* CreateTransferInfo( | 294 static base::DictionaryValue* CreateTransferInfo( |
| 210 UsbTransferStatus status, | 295 UsbTransferStatus status, |
| 211 scoped_refptr<net::IOBuffer> data, | 296 scoped_refptr<net::IOBuffer> data, |
| 212 size_t length) { | 297 size_t length) { |
| 213 base::DictionaryValue* result = new base::DictionaryValue(); | 298 base::DictionaryValue* result = new base::DictionaryValue(); |
| 214 result->SetInteger(kResultCodeKey, status); | 299 result->SetInteger(kResultCodeKey, status); |
| 215 result->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer(data->data(), | 300 result->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer(data->data(), |
| 216 length)); | 301 length)); |
| 217 return result; | 302 return result; |
| 218 } | 303 } |
| 219 | 304 |
| 220 static base::Value* PopulateDevice(int handle, int vendor_id, int product_id) { | 305 static base::Value* PopulateDevice(int handle, int vendor_id, int product_id) { |
| 221 Device device; | 306 Device device; |
| 222 device.handle = handle; | 307 device.handle = handle; |
| 223 device.vendor_id = vendor_id; | 308 device.vendor_id = vendor_id; |
| 224 device.product_id = product_id; | 309 device.product_id = product_id; |
| 225 return device.ToValue().release(); | 310 return device.ToValue().release(); |
| 226 } | 311 } |
| 227 | 312 |
| 313 static base::Value* PopulateInterfaceDescriptor(int interface_number, | |
| 314 int alternate_setting, int interface_class, int interface_subclass, | |
| 315 int interface_protocol, | |
| 316 std::vector<linked_ptr<EndpointDescriptor> >* endpoints) { | |
| 317 InterfaceDescriptor descriptor; | |
| 318 descriptor.interface_number = interface_number; | |
| 319 descriptor.alternate_setting = alternate_setting; | |
| 320 descriptor.interface_class = interface_class; | |
| 321 descriptor.interface_subclass = interface_subclass; | |
| 322 descriptor.interface_protocol = interface_subclass; | |
| 323 descriptor.endpoints = *endpoints; | |
| 324 return descriptor.ToValue().release(); | |
| 325 } | |
| 326 | |
| 228 } // namespace | 327 } // namespace |
| 229 | 328 |
| 230 namespace extensions { | 329 namespace extensions { |
| 231 | 330 |
| 232 UsbAsyncApiFunction::UsbAsyncApiFunction() | 331 UsbAsyncApiFunction::UsbAsyncApiFunction() |
| 233 : manager_(NULL) { | 332 : manager_(NULL) { |
| 234 } | 333 } |
| 235 | 334 |
| 236 UsbAsyncApiFunction::~UsbAsyncApiFunction() { | 335 UsbAsyncApiFunction::~UsbAsyncApiFunction() { |
| 237 } | 336 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 267 scoped_refptr<net::IOBuffer> data, | 366 scoped_refptr<net::IOBuffer> data, |
| 268 size_t length) { | 367 size_t length) { |
| 269 if (status != USB_TRANSFER_COMPLETED) | 368 if (status != USB_TRANSFER_COMPLETED) |
| 270 SetError(ConvertTransferStatusToErrorString(status)); | 369 SetError(ConvertTransferStatusToErrorString(status)); |
| 271 | 370 |
| 272 SetResult(CreateTransferInfo(status, data, length)); | 371 SetResult(CreateTransferInfo(status, data, length)); |
| 273 AsyncWorkCompleted(); | 372 AsyncWorkCompleted(); |
| 274 } | 373 } |
| 275 | 374 |
| 276 bool UsbAsyncApiTransferFunction::ConvertDirectionSafely( | 375 bool UsbAsyncApiTransferFunction::ConvertDirectionSafely( |
| 277 const Direction& input, UsbDevice::TransferDirection* output) { | 376 const Direction& input, UsbEndpointDirection* output) { |
| 278 const bool converted = ConvertDirection(input, output); | 377 const bool converted = ConvertDirection(input, output); |
| 279 if (!converted) | 378 if (!converted) |
| 280 SetError(kErrorConvertDirection); | 379 SetError(kErrorConvertDirection); |
| 281 return converted; | 380 return converted; |
| 282 } | 381 } |
| 283 | 382 |
| 284 bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely( | 383 bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely( |
| 285 const RequestType& input, UsbDevice::TransferRequestType* output) { | 384 const RequestType& input, UsbDevice::TransferRequestType* output) { |
| 286 const bool converted = ConvertRequestType(input, output); | 385 const bool converted = ConvertRequestType(input, output); |
| 287 if (!converted) | 386 if (!converted) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 const uint16_t vendor_id = parameters_->options.vendor_id; | 428 const uint16_t vendor_id = parameters_->options.vendor_id; |
| 330 const uint16_t product_id = parameters_->options.product_id; | 429 const uint16_t product_id = parameters_->options.product_id; |
| 331 UsbDevicePermission::CheckParam param(vendor_id, product_id); | 430 UsbDevicePermission::CheckParam param(vendor_id, product_id); |
| 332 if (!GetExtension()->CheckAPIPermissionWithParam( | 431 if (!GetExtension()->CheckAPIPermissionWithParam( |
| 333 APIPermission::kUsbDevice, ¶m)) { | 432 APIPermission::kUsbDevice, ¶m)) { |
| 334 LOG(WARNING) << "Insufficient permissions to access device."; | 433 LOG(WARNING) << "Insufficient permissions to access device."; |
| 335 CompleteWithError(kErrorPermissionDenied); | 434 CompleteWithError(kErrorPermissionDenied); |
| 336 return; | 435 return; |
| 337 } | 436 } |
| 338 | 437 |
| 339 UsbService* const service = UsbServiceFactory::GetInstance()->GetForProfile( | 438 UsbService* const service = UsbServiceFactory::GetInstance()->GetForProfile( |
|
Bei Zhang
2013/05/14 20:55:47
This is why we get fatal error in profile_keyed_ba
Kenny Root (Google)
2013/05/15 04:43:13
Oh, that makes sense. I was combing all over my ch
| |
| 340 profile()); | 439 profile()); |
| 341 if (!service) { | 440 if (!service) { |
| 342 LOG(WARNING) << "Could not get UsbService for active profile."; | 441 LOG(WARNING) << "Could not get UsbService for active profile."; |
| 343 CompleteWithError(kErrorNoDevice); | 442 CompleteWithError(kErrorNoDevice); |
| 344 return; | 443 return; |
| 345 } | 444 } |
| 346 | 445 |
| 347 service->FindDevices(vendor_id, product_id, &devices_, base::Bind( | 446 service->FindDevices(vendor_id, product_id, &devices_, base::Bind( |
| 348 &UsbFindDevicesFunction::OnCompleted, this)); | 447 &UsbFindDevicesFunction::OnCompleted, this)); |
| 349 } | 448 } |
| 350 | 449 |
| 351 void UsbFindDevicesFunction::OnCompleted() { | 450 void UsbFindDevicesFunction::OnCompleted() { |
| 352 for (size_t i = 0; i < devices_.size(); ++i) { | 451 for (size_t i = 0; i < devices_.size(); ++i) { |
| 353 UsbDevice* const device = devices_[i]; | 452 UsbDevice* const device = devices_[i]; |
| 354 UsbDeviceResource* const resource = new UsbDeviceResource( | 453 UsbDeviceResource* const resource = new UsbDeviceResource( |
| 355 extension_->id(), device); | 454 extension_->id(), device); |
| 356 | 455 |
| 357 Device js_device; | 456 Device js_device; |
| 358 result_->Append(PopulateDevice(manager_->Add(resource), | 457 result_->Append(PopulateDevice(manager_->Add(resource), |
| 359 parameters_->options.vendor_id, | 458 parameters_->options.vendor_id, |
| 360 parameters_->options.product_id)); | 459 parameters_->options.product_id)); |
| 361 } | 460 } |
| 362 | 461 |
| 363 SetResult(result_.release()); | 462 SetResult(result_.release()); |
| 364 AsyncWorkCompleted(); | 463 AsyncWorkCompleted(); |
| 365 } | 464 } |
| 366 | 465 |
| 466 UsbListInterfacesFunction::UsbListInterfacesFunction() {} | |
| 467 | |
| 468 UsbListInterfacesFunction::~UsbListInterfacesFunction() {} | |
| 469 | |
| 470 bool UsbListInterfacesFunction::Prepare() { | |
| 471 parameters_ = ListInterfaces::Params::Create(*args_); | |
| 472 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | |
| 473 return true; | |
| 474 } | |
| 475 | |
| 476 void UsbListInterfacesFunction::AsyncWorkStart() { | |
| 477 UsbDeviceResource* const resource = GetUsbDeviceResource( | |
| 478 parameters_->device.handle); | |
| 479 if (!resource) { | |
| 480 CompleteWithError(kErrorNoDevice); | |
| 481 return; | |
| 482 } | |
| 483 | |
| 484 config_ = new UsbConfigDescriptor(); | |
| 485 resource->device()->ListInterfaces(config_, base::Bind( | |
| 486 &UsbListInterfacesFunction::OnCompleted, this)); | |
| 487 RemoveUsbDeviceResource(parameters_->device.handle); | |
|
Bei Zhang
2013/05/14 20:55:47
Please remove this.
If removing this causes crash
Kenny Root (Google)
2013/05/15 04:43:13
Done.
| |
| 488 } | |
| 489 | |
| 490 void UsbListInterfacesFunction::OnCompleted(bool success) { | |
| 491 if (!success) { | |
| 492 SetError(kErrorCannotListInterfaces); | |
| 493 AsyncWorkCompleted(); | |
| 494 return; | |
| 495 } | |
| 496 | |
| 497 result_.reset(new base::ListValue()); | |
| 498 | |
| 499 for (size_t i = 0, numInterfaces = config_->GetNumInterfaces(); | |
| 500 i < numInterfaces; ++i) { | |
| 501 scoped_refptr<const UsbInterface> usbInterface(config_->GetInterface(i)); | |
| 502 for (size_t j = 0, numDescriptors = usbInterface->GetNumAltSettings(); | |
| 503 j < numDescriptors; ++j) { | |
| 504 scoped_refptr<const UsbInterfaceDescriptor> descriptor | |
| 505 = usbInterface->GetAltSetting(j); | |
| 506 std::vector<linked_ptr<EndpointDescriptor> > endpoints; | |
| 507 for (size_t k = 0, numEndpoints = descriptor->GetNumEndpoints(); | |
| 508 k < numEndpoints; k++) { | |
| 509 scoped_refptr<const UsbEndpointDescriptor> endpoint | |
| 510 = descriptor->GetEndpoint(k); | |
| 511 linked_ptr<EndpointDescriptor> endpoint_desc(new EndpointDescriptor()); | |
| 512 | |
| 513 TransferType type; | |
| 514 Direction direction; | |
| 515 SynchronizationType synchronization; | |
| 516 UsageType usage; | |
| 517 | |
| 518 if (!ConvertTransferTypeSafely(endpoint->GetTransferType(), &type) || | |
| 519 !ConvertDirectionSafely(endpoint->GetDirection(), &direction) || | |
| 520 !ConvertSynchronizationTypeSafely( | |
| 521 endpoint->GetSynchronizationType(), &synchronization) || | |
| 522 !ConvertUsageTypeSafely(endpoint->GetUsageType(), &usage)) { | |
| 523 SetError(kErrorCannotListInterfaces); | |
| 524 AsyncWorkCompleted(); | |
| 525 return; | |
| 526 } | |
| 527 | |
| 528 endpoint_desc->address = endpoint->GetAddress(); | |
| 529 endpoint_desc->type = type; | |
| 530 endpoint_desc->direction = direction; | |
| 531 endpoint_desc->maximum_packet_size = endpoint->GetMaximumPacketSize(); | |
| 532 endpoint_desc->synchronization = synchronization; | |
| 533 endpoint_desc->usage = usage; | |
| 534 | |
| 535 int* polling_interval = new int; | |
| 536 endpoint_desc->polling_interval.reset(polling_interval); | |
| 537 *polling_interval = endpoint->GetPollingInterval(); | |
| 538 | |
| 539 endpoints.push_back(endpoint_desc); | |
| 540 } | |
| 541 | |
| 542 result_->Append(PopulateInterfaceDescriptor( | |
| 543 descriptor->GetInterfaceNumber(), | |
| 544 descriptor->GetAlternateSetting(), | |
| 545 descriptor->GetInterfaceClass(), | |
| 546 descriptor->GetInterfaceSubclass(), | |
| 547 descriptor->GetInterfaceProtocol(), | |
| 548 &endpoints)); | |
| 549 } | |
| 550 } | |
| 551 | |
| 552 SetResult(result_.release()); | |
| 553 AsyncWorkCompleted(); | |
| 554 } | |
| 555 | |
| 556 bool UsbListInterfacesFunction::ConvertDirectionSafely( | |
| 557 const UsbEndpointDirection& input, | |
| 558 extensions::api::usb::Direction* output) { | |
| 559 const bool converted = ConvertDirectionToApi(input, output); | |
| 560 if (!converted) | |
| 561 SetError(kErrorConvertDirection); | |
| 562 return converted; | |
| 563 } | |
| 564 | |
| 565 bool UsbListInterfacesFunction::ConvertSynchronizationTypeSafely( | |
| 566 const UsbSynchronizationType& input, | |
| 567 extensions::api::usb::SynchronizationType* output) { | |
| 568 const bool converted = ConvertSynchronizationTypeToApi(input, output); | |
| 569 if (!converted) | |
| 570 SetError(kErrorConvertSynchronizationType); | |
| 571 return converted; | |
| 572 } | |
| 573 | |
| 574 bool UsbListInterfacesFunction::ConvertTransferTypeSafely( | |
| 575 const UsbTransferType& input, | |
| 576 extensions::api::usb::TransferType* output) { | |
| 577 const bool converted = ConvertTransferTypeToApi(input, output); | |
| 578 if (!converted) | |
| 579 SetError(kErrorConvertTransferType); | |
| 580 return converted; | |
| 581 } | |
| 582 | |
| 583 bool UsbListInterfacesFunction::ConvertUsageTypeSafely( | |
| 584 const UsbUsageType& input, | |
| 585 extensions::api::usb::UsageType* output) { | |
| 586 const bool converted = ConvertUsageTypeToApi(input, output); | |
| 587 if (!converted) | |
| 588 SetError(kErrorConvertUsageType); | |
| 589 return converted; | |
| 590 } | |
| 591 | |
| 367 UsbCloseDeviceFunction::UsbCloseDeviceFunction() {} | 592 UsbCloseDeviceFunction::UsbCloseDeviceFunction() {} |
| 368 | 593 |
| 369 UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {} | 594 UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {} |
| 370 | 595 |
| 371 bool UsbCloseDeviceFunction::Prepare() { | 596 bool UsbCloseDeviceFunction::Prepare() { |
| 372 parameters_ = CloseDevice::Params::Create(*args_); | 597 parameters_ = CloseDevice::Params::Create(*args_); |
| 373 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 598 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 374 return true; | 599 return true; |
| 375 } | 600 } |
| 376 | 601 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 void UsbControlTransferFunction::AsyncWorkStart() { | 717 void UsbControlTransferFunction::AsyncWorkStart() { |
| 493 UsbDeviceResource* const resource = GetUsbDeviceResource( | 718 UsbDeviceResource* const resource = GetUsbDeviceResource( |
| 494 parameters_->device.handle); | 719 parameters_->device.handle); |
| 495 if (!resource) { | 720 if (!resource) { |
| 496 CompleteWithError(kErrorNoDevice); | 721 CompleteWithError(kErrorNoDevice); |
| 497 return; | 722 return; |
| 498 } | 723 } |
| 499 | 724 |
| 500 const ControlTransferInfo& transfer = parameters_->transfer_info; | 725 const ControlTransferInfo& transfer = parameters_->transfer_info; |
| 501 | 726 |
| 502 UsbDevice::TransferDirection direction; | 727 UsbEndpointDirection direction; |
| 503 UsbDevice::TransferRequestType request_type; | 728 UsbDevice::TransferRequestType request_type; |
| 504 UsbDevice::TransferRecipient recipient; | 729 UsbDevice::TransferRecipient recipient; |
| 505 size_t size = 0; | 730 size_t size = 0; |
| 506 | 731 |
| 507 if (!ConvertDirectionSafely(transfer.direction, &direction) || | 732 if (!ConvertDirectionSafely(transfer.direction, &direction) || |
| 508 !ConvertRequestTypeSafely(transfer.request_type, &request_type) || | 733 !ConvertRequestTypeSafely(transfer.request_type, &request_type) || |
| 509 !ConvertRecipientSafely(transfer.recipient, &recipient)) { | 734 !ConvertRecipientSafely(transfer.recipient, &recipient)) { |
| 510 AsyncWorkCompleted(); | 735 AsyncWorkCompleted(); |
| 511 return; | 736 return; |
| 512 } | 737 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 541 void UsbBulkTransferFunction::AsyncWorkStart() { | 766 void UsbBulkTransferFunction::AsyncWorkStart() { |
| 542 UsbDeviceResource* const resource = GetUsbDeviceResource( | 767 UsbDeviceResource* const resource = GetUsbDeviceResource( |
| 543 parameters_->device.handle); | 768 parameters_->device.handle); |
| 544 if (!resource) { | 769 if (!resource) { |
| 545 CompleteWithError(kErrorNoDevice); | 770 CompleteWithError(kErrorNoDevice); |
| 546 return; | 771 return; |
| 547 } | 772 } |
| 548 | 773 |
| 549 const GenericTransferInfo& transfer = parameters_->transfer_info; | 774 const GenericTransferInfo& transfer = parameters_->transfer_info; |
| 550 | 775 |
| 551 UsbDevice::TransferDirection direction; | 776 UsbEndpointDirection direction; |
| 552 size_t size = 0; | 777 size_t size = 0; |
| 553 | 778 |
| 554 if (!ConvertDirectionSafely(transfer.direction, &direction)) { | 779 if (!ConvertDirectionSafely(transfer.direction, &direction)) { |
| 555 AsyncWorkCompleted(); | 780 AsyncWorkCompleted(); |
| 556 return; | 781 return; |
| 557 } | 782 } |
| 558 | 783 |
| 559 if (!GetTransferSize(transfer, &size)) { | 784 if (!GetTransferSize(transfer, &size)) { |
| 560 CompleteWithError(kErrorInvalidTransferLength); | 785 CompleteWithError(kErrorInvalidTransferLength); |
| 561 return; | 786 return; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 585 void UsbInterruptTransferFunction::AsyncWorkStart() { | 810 void UsbInterruptTransferFunction::AsyncWorkStart() { |
| 586 UsbDeviceResource* const resource = GetUsbDeviceResource( | 811 UsbDeviceResource* const resource = GetUsbDeviceResource( |
| 587 parameters_->device.handle); | 812 parameters_->device.handle); |
| 588 if (!resource) { | 813 if (!resource) { |
| 589 CompleteWithError(kErrorNoDevice); | 814 CompleteWithError(kErrorNoDevice); |
| 590 return; | 815 return; |
| 591 } | 816 } |
| 592 | 817 |
| 593 const GenericTransferInfo& transfer = parameters_->transfer_info; | 818 const GenericTransferInfo& transfer = parameters_->transfer_info; |
| 594 | 819 |
| 595 UsbDevice::TransferDirection direction; | 820 UsbEndpointDirection direction; |
| 596 size_t size = 0; | 821 size_t size = 0; |
| 597 | 822 |
| 598 if (!ConvertDirectionSafely(transfer.direction, &direction)) { | 823 if (!ConvertDirectionSafely(transfer.direction, &direction)) { |
| 599 AsyncWorkCompleted(); | 824 AsyncWorkCompleted(); |
| 600 return; | 825 return; |
| 601 } | 826 } |
| 602 | 827 |
| 603 if (!GetTransferSize(transfer, &size)) { | 828 if (!GetTransferSize(transfer, &size)) { |
| 604 CompleteWithError(kErrorInvalidTransferLength); | 829 CompleteWithError(kErrorInvalidTransferLength); |
| 605 return; | 830 return; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 631 parameters_->device.handle); | 856 parameters_->device.handle); |
| 632 if (!resource) { | 857 if (!resource) { |
| 633 CompleteWithError(kErrorNoDevice); | 858 CompleteWithError(kErrorNoDevice); |
| 634 return; | 859 return; |
| 635 } | 860 } |
| 636 | 861 |
| 637 const IsochronousTransferInfo& transfer = parameters_->transfer_info; | 862 const IsochronousTransferInfo& transfer = parameters_->transfer_info; |
| 638 const GenericTransferInfo& generic_transfer = transfer.transfer_info; | 863 const GenericTransferInfo& generic_transfer = transfer.transfer_info; |
| 639 | 864 |
| 640 size_t size = 0; | 865 size_t size = 0; |
| 641 UsbDevice::TransferDirection direction; | 866 UsbEndpointDirection direction; |
| 642 | 867 |
| 643 if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) { | 868 if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) { |
| 644 AsyncWorkCompleted(); | 869 AsyncWorkCompleted(); |
| 645 return; | 870 return; |
| 646 } | 871 } |
| 647 if (!GetTransferSize(generic_transfer, &size)) { | 872 if (!GetTransferSize(generic_transfer, &size)) { |
| 648 CompleteWithError(kErrorInvalidTransferLength); | 873 CompleteWithError(kErrorInvalidTransferLength); |
| 649 return; | 874 return; |
| 650 } | 875 } |
| 651 if (transfer.packets < 0 || transfer.packets >= kMaxPackets) { | 876 if (transfer.packets < 0 || transfer.packets >= kMaxPackets) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 734 } | 959 } |
| 735 | 960 |
| 736 void UsbResetDeviceFunction::OnError() { | 961 void UsbResetDeviceFunction::OnError() { |
| 737 RemoveUsbDeviceResource(parameters_->device.handle); | 962 RemoveUsbDeviceResource(parameters_->device.handle); |
| 738 SetError(kErrorResetDevice); | 963 SetError(kErrorResetDevice); |
| 739 SetResult(Value::CreateBooleanValue(false)); | 964 SetResult(Value::CreateBooleanValue(false)); |
| 740 AsyncWorkCompleted(); | 965 AsyncWorkCompleted(); |
| 741 } | 966 } |
| 742 | 967 |
| 743 } // namespace extensions | 968 } // namespace extensions |
| OLD | NEW |