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

Side by Side Diff: chrome/browser/extensions/api/usb/usb_device_resource.cc

Issue 10224009: Experimental USB API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review changes. Created 8 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/usb/usb_device_resource.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/synchronization/lock.h"
13 #include "chrome/browser/extensions/api/api_resource_event_notifier.h"
14 #include "chrome/browser/extensions/api/api_resource.h"
15 #include "chrome/browser/usb/usb_device.h"
16 #include "chrome/common/extensions/api/experimental.usb.h"
17
18 using extensions::api::experimental_usb::ControlTransferInfo;
19 using extensions::api::experimental_usb::GenericTransferInfo;
20 using std::string;
21 using std::vector;
22
23 static const char* kDirectionIn = "in";
24 static const char* kDirectionOut = "out";
25
26 static const char* kRequestTypeStandard = "standard";
27 static const char* kRequestTypeClass = "class";
28 static const char* kRequestTypeVendor = "vendor";
29 static const char* kRequestTypeReserved = "reserved";
30
31 static const char* kRecipientDevice = "device";
32 static const char* kRecipientInterface = "interface";
33 static const char* kRecipientEndpoint = "endpoint";
34 static const char* kRecipientOther = "other";
35
36 namespace {
37
38 static bool ConvertDirection(const string& input,
39 UsbDevice::TransferDirection* output) {
40 if (input == kDirectionIn) {
41 *output = UsbDevice::IN;
42 return true;
43 } else if (input == kDirectionOut) {
44 *output = UsbDevice::OUT;
45 return true;
46 }
47 return false;
48 }
49
50 static bool ConvertRequestType(const string& input,
51 UsbDevice::TransferRequestType* output) {
52 if (input == kRequestTypeStandard) {
53 *output = UsbDevice::STANDARD;
54 return true;
55 } else if (input == kRequestTypeClass) {
56 *output = UsbDevice::CLASS;
57 return true;
58 } else if (input == kRequestTypeVendor) {
59 *output = UsbDevice::VENDOR;
60 return true;
61 } else if (input == kRequestTypeReserved) {
62 *output = UsbDevice::RESERVED;
63 return true;
64 }
65 return false;
66 }
67
68 static bool ConvertRecipient(const string& input,
69 UsbDevice::TransferRecipient* output) {
70 if (input == kRecipientDevice) {
71 *output = UsbDevice::DEVICE;
72 return true;
73 } else if (input == kRecipientInterface) {
74 *output = UsbDevice::INTERFACE;
75 return true;
76 } else if (input == kRecipientEndpoint) {
77 *output = UsbDevice::ENDPOINT;
78 return true;
79 } else if (input == kRecipientOther) {
80 *output = UsbDevice::OTHER;
81 return true;
82 }
83 return false;
84 }
85
86 template<class T>
87 static bool GetTransferSize(const T& input, unsigned int* output) {
88 if (input.direction == kDirectionIn) {
89 const int* length = input.length.get();
90 if (length) {
91 *output = *length;
92 return true;
93 }
94 } else if (input.direction == kDirectionOut) {
95 if (input.data.get()) {
96 *output = input.data->size();
97 return true;
98 }
99 }
100 return false;
101 }
102
103 template<class T>
104 static scoped_refptr<net::IOBuffer> CreateBufferForTransfer(const T& input) {
105 unsigned int size = 0;
106 if (!GetTransferSize(input, &size)) {
107 return NULL;
108 }
109
110 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(size);
111 if (!input.data.get()) {
112 return buffer;
113 }
114
115 const vector<int>& input_buffer = *input.data.get();
116 for (unsigned int i = 0; i < size; ++i) {
117 buffer->data()[i] = input_buffer[i];
118 }
119
120 return buffer;
121 }
122
123 } // namespace
124
125 namespace extensions {
126
127 UsbDeviceResource::UsbDeviceResource(APIResourceEventNotifier* notifier,
128 UsbDevice* device)
129 : APIResource(APIResource::UsbDeviceResource, notifier), device_(device),
130 pending_transfers_(0) {}
131
132 UsbDeviceResource::~UsbDeviceResource() {
133 if (pending_transfers_) {
134 LOG(ERROR) << "There are transfers still in flight.";
135 }
136 }
137
138 void UsbDeviceResource::ControlTransfer(const ControlTransferInfo& transfer) {
139 UsbDevice::TransferDirection direction;
140 UsbDevice::TransferRequestType request_type;
141 UsbDevice::TransferRecipient recipient;
142 unsigned int size;
143 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(transfer);
144
145 if (!ConvertDirection(transfer.direction, &direction) ||
146 !ConvertRequestType(transfer.request_type, &request_type) ||
147 !ConvertRecipient(transfer.recipient, &recipient) ||
148 !GetTransferSize(transfer, &size) || !buffer) {
149 LOG(INFO) << "Malformed transfer parameters.";
150 return;
151 }
152
153 device_->ControlTransfer(direction, request_type, recipient, transfer.request,
154 transfer.value, transfer.index, buffer, size, 0,
155 base::Bind(&UsbDeviceResource::TransferComplete,
156 base::Unretained(this), buffer, size));
157 }
158
159 void UsbDeviceResource::InterruptTransfer(const GenericTransferInfo& transfer) {
160 unsigned int size;
161 UsbDevice::TransferDirection direction;
162 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(transfer);
163
164 if (!ConvertDirection(transfer.direction, &direction) ||
165 !GetTransferSize(transfer, &size) || !buffer) {
166 LOG(INFO) << "Malformed transfer parameters.";
167 return;
168 }
169
170 device_->InterruptTransfer(direction, transfer.endpoint, buffer, size, 0,
171 base::Bind(&UsbDeviceResource::TransferComplete,
172 base::Unretained(this), buffer, size));
173 }
174
175 void UsbDeviceResource::BulkTransfer(const GenericTransferInfo& transfer) {
176 unsigned int size;
177 UsbDevice::TransferDirection direction;
178 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(transfer);
179
180 if (!ConvertDirection(transfer.direction, &direction) ||
181 !GetTransferSize(transfer, &size) || !buffer) {
182 LOG(INFO) << "Malformed transfer parameters.";
183 return;
184 }
185
186 device_->BulkTransfer(direction, transfer.endpoint, buffer, size, 0,
187 base::Bind(&UsbDeviceResource::TransferComplete,
188 base::Unretained(this), buffer, size));
189 }
190
191 void UsbDeviceResource::TransferComplete(net::IOBuffer* buffer,
192 const size_t length,
193 int success) {
194 if (buffer) {
195 base::ListValue *const response_buffer = new base::ListValue();
196 for (unsigned int i = 0; i < length; ++i) {
197 const uint8_t value = buffer->data()[i] & 0xFF;
198 response_buffer->Append(base::Value::CreateIntegerValue(value));
199 }
200 event_notifier()->OnTransferComplete(success, response_buffer);
201 }
202 }
203
204 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698