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 CloseDevice = extensions::api::usb::CloseDevice; | 21 namespace CloseDevice = extensions::api::usb::CloseDevice; |
22 namespace ControlTransfer = extensions::api::usb::ControlTransfer; | 22 namespace ControlTransfer = extensions::api::usb::ControlTransfer; |
23 namespace FindDevices = extensions::api::usb::FindDevices; | 23 namespace FindDevices = extensions::api::usb::FindDevices; |
24 namespace InterruptTransfer = extensions::api::usb::InterruptTransfer; | 24 namespace InterruptTransfer = extensions::api::usb::InterruptTransfer; |
25 namespace IsochronousTransfer = extensions::api::usb::IsochronousTransfer; | 25 namespace IsochronousTransfer = extensions::api::usb::IsochronousTransfer; |
26 namespace ReleaseInterface = extensions::api::usb::ReleaseInterface; | 26 namespace ReleaseInterface = extensions::api::usb::ReleaseInterface; |
27 namespace SetInterfaceAlternateSetting = | 27 namespace SetInterfaceAlternateSetting = |
28 extensions::api::usb::SetInterfaceAlternateSetting; | 28 extensions::api::usb::SetInterfaceAlternateSetting; |
| 29 namespace usb = extensions::api::usb; |
29 | 30 |
30 using extensions::api::usb::ControlTransferInfo; | |
31 using extensions::api::usb::Device; | |
32 using extensions::api::usb::GenericTransferInfo; | |
33 using extensions::api::usb::IsochronousTransferInfo; | |
34 using std::string; | 31 using std::string; |
35 using std::vector; | 32 using std::vector; |
| 33 using usb::ControlTransferInfo; |
| 34 using usb::Device; |
| 35 using usb::Direction; |
| 36 using usb::GenericTransferInfo; |
| 37 using usb::IsochronousTransferInfo; |
| 38 using usb::Recipient; |
| 39 using usb::RequestType; |
36 | 40 |
37 namespace { | 41 namespace { |
38 | 42 |
39 static const char* kDataKey = "data"; | 43 static const char* kDataKey = "data"; |
40 static const char* kResultCodeKey = "resultCode"; | 44 static const char* kResultCodeKey = "resultCode"; |
41 | 45 |
42 static const char* kDirectionIn = "in"; | |
43 static const char* kDirectionOut = "out"; | |
44 | |
45 static const char* kRequestTypeClass = "class"; | |
46 static const char* kRequestTypeReserved = "reserved"; | |
47 static const char* kRequestTypeStandard = "standard"; | |
48 static const char* kRequestTypeVendor = "vendor"; | |
49 | |
50 static const char* kRecipientDevice = "device"; | |
51 static const char* kRecipientEndpoint = "endpoint"; | |
52 static const char* kRecipientInterface = "interface"; | |
53 static const char* kRecipientOther = "other"; | |
54 | |
55 static const char* kErrorCancelled = "Transfer was cancelled."; | 46 static const char* kErrorCancelled = "Transfer was cancelled."; |
56 static const char* kErrorDisconnect = "Device disconnected."; | 47 static const char* kErrorDisconnect = "Device disconnected."; |
57 static const char* kErrorGeneric = "Transfer failed."; | 48 static const char* kErrorGeneric = "Transfer failed."; |
58 static const char* kErrorOverflow = "Inbound transfer overflow."; | 49 static const char* kErrorOverflow = "Inbound transfer overflow."; |
59 static const char* kErrorStalled = "Transfer stalled."; | 50 static const char* kErrorStalled = "Transfer stalled."; |
60 static const char* kErrorTimeout = "Transfer timed out."; | 51 static const char* kErrorTimeout = "Transfer timed out."; |
61 static const char* kErrorTransferLength = "Transfer length is insufficient."; | 52 static const char* kErrorTransferLength = "Transfer length is insufficient."; |
62 | 53 |
63 static const char* kErrorCannotClaimInterface = "Error claiming interface."; | 54 static const char* kErrorCannotClaimInterface = "Error claiming interface."; |
64 static const char* kErrorCannotReleaseInterface = "Error releasing interface."; | 55 static const char* kErrorCannotReleaseInterface = "Error releasing interface."; |
65 static const char* kErrorCannotSetInterfaceAlternateSetting = | 56 static const char* kErrorCannotSetInterfaceAlternateSetting = |
66 "Error setting alternate interface setting."; | 57 "Error setting alternate interface setting."; |
67 static const char* kErrorConvertDirection = "Invalid transfer direction."; | 58 static const char* kErrorConvertDirection = "Invalid transfer direction."; |
68 static const char* kErrorConvertRecipient = "Invalid transfer recipient."; | 59 static const char* kErrorConvertRecipient = "Invalid transfer recipient."; |
69 static const char* kErrorConvertRequestType = "Invalid request type."; | 60 static const char* kErrorConvertRequestType = "Invalid request type."; |
70 static const char* kErrorMalformedParameters = "Error parsing parameters."; | 61 static const char* kErrorMalformedParameters = "Error parsing parameters."; |
71 static const char* kErrorNoDevice = "No such device."; | 62 static const char* kErrorNoDevice = "No such device."; |
72 static const char* kErrorPermissionDenied = | 63 static const char* kErrorPermissionDenied = |
73 "Permission to access device was denied"; | 64 "Permission to access device was denied"; |
74 | 65 |
75 static UsbDevice* device_for_test_ = NULL; | 66 static UsbDevice* device_for_test_ = NULL; |
76 | 67 |
77 static bool ConvertDirection(const string& input, | 68 static bool ConvertDirection(const Direction& input, |
78 UsbDevice::TransferDirection* output) { | 69 UsbDevice::TransferDirection* output) { |
79 if (input == kDirectionIn) { | 70 switch (input) { |
80 *output = UsbDevice::INBOUND; | 71 case usb::USB_DIRECTION_IN: |
81 return true; | 72 *output = UsbDevice::INBOUND; |
82 } else if (input == kDirectionOut) { | 73 return true; |
83 *output = UsbDevice::OUTBOUND; | 74 case usb::USB_DIRECTION_OUT: |
84 return true; | 75 *output = UsbDevice::OUTBOUND; |
| 76 return true; |
| 77 default: |
| 78 return false; |
85 } | 79 } |
| 80 NOTREACHED(); |
86 return false; | 81 return false; |
87 } | 82 } |
88 | 83 |
89 static bool ConvertRequestType(const string& input, | 84 static bool ConvertRequestType(const RequestType& input, |
90 UsbDevice::TransferRequestType* output) { | 85 UsbDevice::TransferRequestType* output) { |
91 if (input == kRequestTypeStandard) { | 86 switch (input) { |
92 *output = UsbDevice::STANDARD; | 87 case usb::USB_REQUEST_TYPE_STANDARD: |
93 return true; | 88 *output = UsbDevice::STANDARD; |
94 } else if (input == kRequestTypeClass) { | 89 return true; |
95 *output = UsbDevice::CLASS; | 90 case usb::USB_REQUEST_TYPE_CLASS: |
96 return true; | 91 *output = UsbDevice::CLASS; |
97 } else if (input == kRequestTypeVendor) { | 92 return true; |
98 *output = UsbDevice::VENDOR; | 93 case usb::USB_REQUEST_TYPE_VENDOR: |
99 return true; | 94 *output = UsbDevice::VENDOR; |
100 } else if (input == kRequestTypeReserved) { | 95 return true; |
101 *output = UsbDevice::RESERVED; | 96 case usb::USB_REQUEST_TYPE_RESERVED: |
102 return true; | 97 *output = UsbDevice::RESERVED; |
| 98 return true; |
| 99 default: |
| 100 return false; |
103 } | 101 } |
| 102 NOTREACHED(); |
104 return false; | 103 return false; |
105 } | 104 } |
106 | 105 |
107 static bool ConvertRecipient(const string& input, | 106 static bool ConvertRecipient(const Recipient& input, |
108 UsbDevice::TransferRecipient* output) { | 107 UsbDevice::TransferRecipient* output) { |
109 if (input == kRecipientDevice) { | 108 switch (input) { |
110 *output = UsbDevice::DEVICE; | 109 case usb::USB_RECIPIENT_DEVICE: |
111 return true; | 110 *output = UsbDevice::DEVICE; |
112 } else if (input == kRecipientInterface) { | 111 return true; |
113 *output = UsbDevice::INTERFACE; | 112 case usb::USB_RECIPIENT_INTERFACE: |
114 return true; | 113 *output = UsbDevice::INTERFACE; |
115 } else if (input == kRecipientEndpoint) { | 114 return true; |
116 *output = UsbDevice::ENDPOINT; | 115 case usb::USB_RECIPIENT_ENDPOINT: |
117 return true; | 116 *output = UsbDevice::ENDPOINT; |
118 } else if (input == kRecipientOther) { | 117 return true; |
119 *output = UsbDevice::OTHER; | 118 case usb::USB_RECIPIENT_OTHER: |
120 return true; | 119 *output = UsbDevice::OTHER; |
| 120 return true; |
| 121 default: |
| 122 return false; |
121 } | 123 } |
| 124 NOTREACHED(); |
122 return false; | 125 return false; |
123 } | 126 } |
124 | 127 |
125 template<class T> | 128 template<class T> |
126 static bool GetTransferSize(const T& input, size_t* output) { | 129 static bool GetTransferSize(const T& input, size_t* output) { |
127 if (input.direction == kDirectionIn) { | 130 if (input.direction == usb::USB_DIRECTION_IN) { |
128 const int* length = input.length.get(); | 131 const int* length = input.length.get(); |
129 if (length) { | 132 if (length) { |
130 *output = *length; | 133 *output = *length; |
131 return true; | 134 return true; |
132 } | 135 } |
133 } else if (input.direction == kDirectionOut) { | 136 } else if (input.direction == usb::USB_DIRECTION_OUT) { |
134 if (input.data.get()) { | 137 if (input.data.get()) { |
135 *output = input.data->size(); | 138 *output = input.data->size(); |
136 return true; | 139 return true; |
137 } | 140 } |
138 } | 141 } |
139 return false; | 142 return false; |
140 } | 143 } |
141 | 144 |
142 template<class T> | 145 template<class T> |
143 static scoped_refptr<net::IOBuffer> CreateBufferForTransfer(const T& input) { | 146 static scoped_refptr<net::IOBuffer> CreateBufferForTransfer(const T& input) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 scoped_refptr<net::IOBuffer> data, | 246 scoped_refptr<net::IOBuffer> data, |
244 size_t length) { | 247 size_t length) { |
245 if (status != USB_TRANSFER_COMPLETED) | 248 if (status != USB_TRANSFER_COMPLETED) |
246 SetError(ConvertTransferStatusToErrorString(status)); | 249 SetError(ConvertTransferStatusToErrorString(status)); |
247 | 250 |
248 SetResult(CreateTransferInfo(status, data, length)); | 251 SetResult(CreateTransferInfo(status, data, length)); |
249 AsyncWorkCompleted(); | 252 AsyncWorkCompleted(); |
250 } | 253 } |
251 | 254 |
252 bool UsbAsyncApiTransferFunction::ConvertDirectionSafely( | 255 bool UsbAsyncApiTransferFunction::ConvertDirectionSafely( |
253 const string& input, UsbDevice::TransferDirection* output) { | 256 const Direction& input, UsbDevice::TransferDirection* output) { |
254 const bool converted = ConvertDirection(input, output); | 257 const bool converted = ConvertDirection(input, output); |
255 if (!converted) | 258 if (!converted) |
256 SetError(kErrorConvertDirection); | 259 SetError(kErrorConvertDirection); |
257 return converted; | 260 return converted; |
258 } | 261 } |
259 | 262 |
260 bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely( | 263 bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely( |
261 const string& input, UsbDevice::TransferRequestType* output) { | 264 const RequestType& input, UsbDevice::TransferRequestType* output) { |
262 const bool converted = ConvertRequestType(input, output); | 265 const bool converted = ConvertRequestType(input, output); |
263 if (!converted) | 266 if (!converted) |
264 SetError(kErrorConvertRequestType); | 267 SetError(kErrorConvertRequestType); |
265 return converted; | 268 return converted; |
266 } | 269 } |
267 | 270 |
268 bool UsbAsyncApiTransferFunction::ConvertRecipientSafely( | 271 bool UsbAsyncApiTransferFunction::ConvertRecipientSafely( |
269 const string& input, UsbDevice::TransferRecipient* output) { | 272 const Recipient& input, UsbDevice::TransferRecipient* output) { |
270 const bool converted = ConvertRecipient(input, output); | 273 const bool converted = ConvertRecipient(input, output); |
271 if (!converted) | 274 if (!converted) |
272 SetError(kErrorConvertRecipient); | 275 SetError(kErrorConvertRecipient); |
273 return converted; | 276 return converted; |
274 } | 277 } |
275 | 278 |
276 UsbFindDevicesFunction::UsbFindDevicesFunction() {} | 279 UsbFindDevicesFunction::UsbFindDevicesFunction() {} |
277 | 280 |
278 UsbFindDevicesFunction::~UsbFindDevicesFunction() {} | 281 UsbFindDevicesFunction::~UsbFindDevicesFunction() {} |
279 | 282 |
(...skipping 14 matching lines...) Expand all Loading... |
294 UsbDeviceResource* const resource = new UsbDeviceResource( | 297 UsbDeviceResource* const resource = new UsbDeviceResource( |
295 extension_->id(), NULL, device_for_test_); | 298 extension_->id(), NULL, device_for_test_); |
296 | 299 |
297 Device device; | 300 Device device; |
298 result->Append(PopulateDevice(manager_->Add(resource), 0, 0)); | 301 result->Append(PopulateDevice(manager_->Add(resource), 0, 0)); |
299 SetResult(result.release()); | 302 SetResult(result.release()); |
300 AsyncWorkCompleted(); | 303 AsyncWorkCompleted(); |
301 return; | 304 return; |
302 } | 305 } |
303 | 306 |
304 UsbDevicePermission::CheckParam param( | 307 const uint16_t vendor_id = parameters_->options.vendor_id; |
305 parameters_->vendor_id, parameters_->product_id); | 308 const uint16_t product_id = parameters_->options.product_id; |
| 309 UsbDevicePermission::CheckParam param(vendor_id, product_id); |
306 if (!GetExtension()->CheckAPIPermissionWithParam( | 310 if (!GetExtension()->CheckAPIPermissionWithParam( |
307 APIPermission::kUsbDevice, ¶m)) { | 311 APIPermission::kUsbDevice, ¶m)) { |
308 LOG(WARNING) << "Insufficient permissions to access device."; | 312 LOG(WARNING) << "Insufficient permissions to access device."; |
309 CompleteWithError(kErrorPermissionDenied); | 313 CompleteWithError(kErrorPermissionDenied); |
310 return; | 314 return; |
311 } | 315 } |
312 | 316 |
313 UsbService* const service = UsbServiceFactory::GetInstance()->GetForProfile( | 317 UsbService* const service = UsbServiceFactory::GetInstance()->GetForProfile( |
314 profile()); | 318 profile()); |
315 if (!service) { | 319 if (!service) { |
316 LOG(WARNING) << "Could not get UsbService for active profile."; | 320 LOG(WARNING) << "Could not get UsbService for active profile."; |
317 CompleteWithError(kErrorNoDevice); | 321 CompleteWithError(kErrorNoDevice); |
318 return; | 322 return; |
319 } | 323 } |
320 | 324 |
321 vector<scoped_refptr<UsbDevice> > devices; | 325 vector<scoped_refptr<UsbDevice> > devices; |
322 service->FindDevices(parameters_->vendor_id, parameters_->product_id, | 326 service->FindDevices(vendor_id, product_id, &devices); |
323 &devices); | |
324 for (size_t i = 0; i < devices.size(); ++i) { | 327 for (size_t i = 0; i < devices.size(); ++i) { |
325 UsbDevice* const device = devices[i]; | 328 UsbDevice* const device = devices[i]; |
326 UsbDeviceResource* const resource = new UsbDeviceResource( | 329 UsbDeviceResource* const resource = new UsbDeviceResource( |
327 extension_->id(), NULL, device); | 330 extension_->id(), NULL, device); |
328 | 331 |
329 Device js_device; | 332 Device js_device; |
330 result->Append(PopulateDevice(manager_->Add(resource), | 333 result->Append(PopulateDevice(manager_->Add(resource), |
331 parameters_->vendor_id, | 334 vendor_id, |
332 parameters_->product_id)); | 335 product_id)); |
333 } | 336 } |
334 | 337 |
335 SetResult(result.release()); | 338 SetResult(result.release()); |
336 AsyncWorkCompleted(); | 339 AsyncWorkCompleted(); |
337 } | 340 } |
338 | 341 |
339 UsbCloseDeviceFunction::UsbCloseDeviceFunction() {} | 342 UsbCloseDeviceFunction::UsbCloseDeviceFunction() {} |
340 | 343 |
341 UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {} | 344 UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {} |
342 | 345 |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 CompleteWithError(kErrorNoDevice); | 605 CompleteWithError(kErrorNoDevice); |
603 return; | 606 return; |
604 } | 607 } |
605 | 608 |
606 device->device()->IsochronousTransfer(direction, generic_transfer.endpoint, | 609 device->device()->IsochronousTransfer(direction, generic_transfer.endpoint, |
607 buffer, size, transfer.packets, transfer.packet_length, 0, base::Bind( | 610 buffer, size, transfer.packets, transfer.packet_length, 0, base::Bind( |
608 &UsbIsochronousTransferFunction::OnCompleted, this)); | 611 &UsbIsochronousTransferFunction::OnCompleted, this)); |
609 } | 612 } |
610 | 613 |
611 } // namespace extensions | 614 } // namespace extensions |
OLD | NEW |