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

Side by Side Diff: chrome/browser/extensions/api/hid/hid_api.cc

Issue 161823002: Clean up HID backend and API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Give HID API some OWNERS Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/hid/hid_api.h" 5 #include "chrome/browser/extensions/api/hid/hid_api.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "chrome/browser/extensions/api/api_resource_manager.h" 10 #include "chrome/browser/extensions/api/api_resource_manager.h"
11 #include "chrome/browser/extensions/api/hid/hid_device_resource.h"
12 #include "chrome/common/extensions/api/hid.h" 11 #include "chrome/common/extensions/api/hid.h"
13 #include "chrome/common/extensions/permissions/usb_device_permission.h" 12 #include "chrome/common/extensions/permissions/usb_device_permission.h"
14 #include "device/hid/hid_connection.h" 13 #include "device/hid/hid_connection.h"
15 #include "device/hid/hid_device_info.h" 14 #include "device/hid/hid_device_info.h"
16 #include "device/hid/hid_service.h" 15 #include "device/hid/hid_service.h"
17 #include "extensions/common/permissions/permissions_data.h" 16 #include "extensions/common/permissions/permissions_data.h"
18 #include "net/base/io_buffer.h" 17 #include "net/base/io_buffer.h"
19 18
20 namespace hid = extensions::api::hid; 19 namespace hid = extensions::api::hid;
21 20
22 using device::HidConnection; 21 using device::HidConnection;
22 using device::HidDeviceInfo;
23 using device::HidService; 23 using device::HidService;
24 using device::HidDeviceInfo;
25 24
26 namespace { 25 namespace {
27 26
28 const char kErrorPermissionDenied[] = "Permission to access device was denied."; 27 const char kErrorPermissionDenied[] = "Permission to access device was denied.";
29 const char kErrorServiceFailed[] = "HID service failed be created."; 28 const char kErrorInvalidDeviceId[] = "Invalid HID device ID.";
30 const char kErrorDeviceNotFound[] = "HID device not found.";
31 const char kErrorFailedToOpenDevice[] = "Failed to open HID device."; 29 const char kErrorFailedToOpenDevice[] = "Failed to open HID device.";
32 const char kErrorConnectionNotFound[] = "Connection not established."; 30 const char kErrorConnectionNotFound[] = "Connection not established.";
33 const char kErrorTransfer[] = "Transfer failed."; 31 const char kErrorTransfer[] = "Transfer failed.";
34 32
35 base::Value* PopulateHidDevice(const HidDeviceInfo& info) {
36 hid::HidDeviceInfo device_info;
37 device_info.path = info.device_id;
38 device_info.product_id = info.product_id;
39 device_info.vendor_id = info.vendor_id;
40 return device_info.ToValue().release();
41 }
42
43 base::Value* PopulateHidConnection(int connection_id, 33 base::Value* PopulateHidConnection(int connection_id,
44 scoped_refptr<HidConnection> connection) { 34 scoped_refptr<HidConnection> connection) {
45 hid::HidConnectInfo connection_value; 35 hid::HidConnectInfo connection_value;
46 connection_value.connection_id = connection_id; 36 connection_value.connection_id = connection_id;
47 return connection_value.ToValue().release(); 37 return connection_value.ToValue().release();
48 } 38 }
49 39
50 } // namespace 40 } // namespace
51 41
52 namespace extensions { 42 namespace extensions {
53 43
54 HidAsyncApiFunction::HidAsyncApiFunction() : manager_(NULL) { 44 HidAsyncApiFunction::HidAsyncApiFunction()
55 } 45 : device_manager_(NULL), connection_manager_(NULL) {}
56 46
57 HidAsyncApiFunction::~HidAsyncApiFunction() {} 47 HidAsyncApiFunction::~HidAsyncApiFunction() {}
58 48
59 bool HidAsyncApiFunction::PrePrepare() { 49 bool HidAsyncApiFunction::PrePrepare() {
60 manager_ = ApiResourceManager<HidConnectionResource>::Get(GetProfile()); 50 device_manager_ = HidDeviceManager::Get(GetProfile());
61 if (!manager_) return false; 51 DCHECK(device_manager_);
52 connection_manager_ =
53 ApiResourceManager<HidConnectionResource>::Get(GetProfile());
54 DCHECK(connection_manager_);
62 set_work_thread_id(content::BrowserThread::FILE); 55 set_work_thread_id(content::BrowserThread::FILE);
63 return true; 56 return true;
64 } 57 }
65 58
66 bool HidAsyncApiFunction::Respond() { return error_.empty(); } 59 bool HidAsyncApiFunction::Respond() {
60 return error_.empty();
61 }
67 62
68 HidConnectionResource* HidAsyncApiFunction::GetHidConnectionResource( 63 HidConnectionResource* HidAsyncApiFunction::GetHidConnectionResource(
69 int api_resource_id) { 64 int api_resource_id) {
70 return manager_->Get(extension_->id(), api_resource_id); 65 return connection_manager_->Get(extension_->id(), api_resource_id);
71 } 66 }
72 67
73 void HidAsyncApiFunction::RemoveHidConnectionResource(int api_resource_id) { 68 void HidAsyncApiFunction::RemoveHidConnectionResource(int api_resource_id) {
74 manager_->Remove(extension_->id(), api_resource_id); 69 connection_manager_->Remove(extension_->id(), api_resource_id);
75 } 70 }
76 71
77 void HidAsyncApiFunction::CompleteWithError(const std::string& error) { 72 void HidAsyncApiFunction::CompleteWithError(const std::string& error) {
78 SetError(error); 73 SetError(error);
79 AsyncWorkCompleted(); 74 AsyncWorkCompleted();
80 } 75 }
81 76
82 HidGetDevicesFunction::HidGetDevicesFunction() {} 77 HidGetDevicesFunction::HidGetDevicesFunction() {}
83 78
84 HidGetDevicesFunction::~HidGetDevicesFunction() {} 79 HidGetDevicesFunction::~HidGetDevicesFunction() {}
85 80
86 bool HidGetDevicesFunction::Prepare() { 81 bool HidGetDevicesFunction::Prepare() {
87 parameters_ = hid::GetDevices::Params::Create(*args_); 82 parameters_ = hid::GetDevices::Params::Create(*args_);
88 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 83 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
89 return true; 84 return true;
90 } 85 }
91 86
92 void HidGetDevicesFunction::AsyncWorkStart() { 87 void HidGetDevicesFunction::AsyncWorkStart() {
93 const uint16_t vendor_id = parameters_->options.vendor_id; 88 const uint16_t vendor_id = parameters_->options.vendor_id;
94 const uint16_t product_id = parameters_->options.product_id; 89 const uint16_t product_id = parameters_->options.product_id;
95 UsbDevicePermission::CheckParam param( 90 UsbDevicePermission::CheckParam param(
96 vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE); 91 vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
97 if (!PermissionsData::CheckAPIPermissionWithParam( 92 if (!PermissionsData::CheckAPIPermissionWithParam(
98 GetExtension(), APIPermission::kUsbDevice, &param)) { 93 GetExtension(), APIPermission::kUsbDevice, &param)) {
99 LOG(WARNING) << "Insufficient permissions to access device."; 94 LOG(WARNING) << "Insufficient permissions to access device.";
100 CompleteWithError(kErrorPermissionDenied); 95 CompleteWithError(kErrorPermissionDenied);
101 return; 96 return;
102 } 97 }
103 98
104 HidService* service = HidService::GetInstance(); 99 SetResult(device_manager_->GetApiDevices(vendor_id, product_id).release());
105 if (!service) {
106 CompleteWithError(kErrorServiceFailed);
107 return;
108 }
109 std::vector<HidDeviceInfo> devices;
110 service->GetDevices(&devices);
111
112 scoped_ptr<base::ListValue> result(new base::ListValue());
113 for (std::vector<HidDeviceInfo>::iterator it = devices.begin();
114 it != devices.end(); it++) {
115 if (it->product_id == product_id &&
116 it->vendor_id == vendor_id)
117 result->Append(PopulateHidDevice(*it));
118 }
119 SetResult(result.release());
120 AsyncWorkCompleted(); 100 AsyncWorkCompleted();
121 } 101 }
122 102
123 HidConnectFunction::HidConnectFunction() {} 103 HidConnectFunction::HidConnectFunction() {}
124 104
125 HidConnectFunction::~HidConnectFunction() {} 105 HidConnectFunction::~HidConnectFunction() {}
126 106
127 bool HidConnectFunction::Prepare() { 107 bool HidConnectFunction::Prepare() {
128 parameters_ = hid::Connect::Params::Create(*args_); 108 parameters_ = hid::Connect::Params::Create(*args_);
129 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 109 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
130 return true; 110 return true;
131 } 111 }
132 112
133 void HidConnectFunction::AsyncWorkStart() { 113 void HidConnectFunction::AsyncWorkStart() {
134 HidService* service = HidService::GetInstance(); 114 device::HidDeviceInfo device_info;
135 if (!service) { 115 if (!device_manager_->GetDeviceInfo(parameters_->device_id, &device_info)) {
136 CompleteWithError(kErrorServiceFailed); 116 CompleteWithError(kErrorInvalidDeviceId);
137 return; 117 return;
138 } 118 }
139 HidDeviceInfo device; 119 HidService* hid_service = HidService::GetInstance();
140 if (!service->GetInfo(parameters_->device_info.path, &device)) { 120 DCHECK(hid_service);
141 CompleteWithError(kErrorDeviceNotFound); 121 scoped_refptr<HidConnection> connection =
142 return; 122 hid_service->Connect(device_info.device_id);
143 }
144 if (device.vendor_id != parameters_->device_info.vendor_id ||
145 device.product_id != parameters_->device_info.product_id) {
146 CompleteWithError(kErrorDeviceNotFound);
147 return;
148 }
149 scoped_refptr<HidConnection> connection = service->Connect(device.device_id);
150 if (!connection) { 123 if (!connection) {
151 CompleteWithError(kErrorFailedToOpenDevice); 124 CompleteWithError(kErrorFailedToOpenDevice);
152 return; 125 return;
153 } 126 }
154 int connection_id = 127 int connection_id = connection_manager_->Add(
155 manager_->Add(new HidConnectionResource(extension_->id(), connection)); 128 new HidConnectionResource(extension_->id(), connection));
156 SetResult(PopulateHidConnection(connection_id, connection)); 129 SetResult(PopulateHidConnection(connection_id, connection));
157 AsyncWorkCompleted(); 130 AsyncWorkCompleted();
158 } 131 }
159 132
160 HidDisconnectFunction::HidDisconnectFunction() {} 133 HidDisconnectFunction::HidDisconnectFunction() {}
161 134
162 HidDisconnectFunction::~HidDisconnectFunction() {} 135 HidDisconnectFunction::~HidDisconnectFunction() {}
163 136
164 bool HidDisconnectFunction::Prepare() { 137 bool HidDisconnectFunction::Prepare() {
165 parameters_ = hid::Disconnect::Params::Create(*args_); 138 parameters_ = hid::Disconnect::Params::Create(*args_);
166 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 139 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
167 return true; 140 return true;
168 } 141 }
169 142
170 void HidDisconnectFunction::AsyncWorkStart() { 143 void HidDisconnectFunction::AsyncWorkStart() {
171 int connection_id = parameters_->connection_id; 144 int connection_id = parameters_->connection_id;
172 HidConnectionResource* resource = 145 HidConnectionResource* resource =
173 manager_->Get(extension_->id(), connection_id); 146 connection_manager_->Get(extension_->id(), connection_id);
174 if (!resource) { 147 if (!resource) {
175 CompleteWithError(kErrorConnectionNotFound); 148 CompleteWithError(kErrorConnectionNotFound);
176 return; 149 return;
177 } 150 }
178 manager_->Remove(extension_->id(), connection_id); 151 connection_manager_->Remove(extension_->id(), connection_id);
179 AsyncWorkCompleted(); 152 AsyncWorkCompleted();
180 } 153 }
181 154
182 HidReceiveFunction::HidReceiveFunction() {} 155 HidReceiveFunction::HidReceiveFunction() {}
183 156
184 HidReceiveFunction::~HidReceiveFunction() {} 157 HidReceiveFunction::~HidReceiveFunction() {}
185 158
186 bool HidReceiveFunction::Prepare() { 159 bool HidReceiveFunction::Prepare() {
187 parameters_ = hid::Receive::Params::Create(*args_); 160 parameters_ = hid::Receive::Params::Create(*args_);
188 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 161 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
189 return true; 162 return true;
190 } 163 }
191 164
192 void HidReceiveFunction::AsyncWorkStart() { 165 void HidReceiveFunction::AsyncWorkStart() {
193 int connection_id = parameters_->connection_id; 166 int connection_id = parameters_->connection_id;
194 HidConnectionResource* resource = 167 HidConnectionResource* resource =
195 manager_->Get(extension_->id(), connection_id); 168 connection_manager_->Get(extension_->id(), connection_id);
196 if (!resource) { 169 if (!resource) {
197 CompleteWithError(kErrorConnectionNotFound); 170 CompleteWithError(kErrorConnectionNotFound);
198 return; 171 return;
199 } 172 }
200 173
201 buffer_ = new net::IOBuffer(parameters_->size); 174 buffer_ = new net::IOBufferWithSize(parameters_->size);
202 resource->connection()->Read( 175 resource->connection()->Read(
203 buffer_, 176 buffer_,
204 parameters_->size,
205 base::Bind(&HidReceiveFunction::OnFinished, this)); 177 base::Bind(&HidReceiveFunction::OnFinished, this));
206 } 178 }
207 179
208 void HidReceiveFunction::OnFinished(bool success, size_t bytes) { 180 void HidReceiveFunction::OnFinished(bool success, size_t bytes) {
209 if (!success) { 181 if (!success) {
210 CompleteWithError(kErrorTransfer); 182 CompleteWithError(kErrorTransfer);
211 return; 183 return;
212 } 184 }
213 185
214 SetResult(base::BinaryValue::CreateWithCopiedBuffer(buffer_->data(), bytes)); 186 SetResult(base::BinaryValue::CreateWithCopiedBuffer(buffer_->data(), bytes));
215 AsyncWorkCompleted(); 187 AsyncWorkCompleted();
216 } 188 }
217 189
218 HidSendFunction::HidSendFunction() {} 190 HidSendFunction::HidSendFunction() {}
219 191
220 HidSendFunction::~HidSendFunction() {} 192 HidSendFunction::~HidSendFunction() {}
221 193
222 bool HidSendFunction::Prepare() { 194 bool HidSendFunction::Prepare() {
223 parameters_ = hid::Send::Params::Create(*args_); 195 parameters_ = hid::Send::Params::Create(*args_);
224 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 196 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
225 return true; 197 return true;
226 } 198 }
227 199
228 void HidSendFunction::AsyncWorkStart() { 200 void HidSendFunction::AsyncWorkStart() {
229 int connection_id = parameters_->connection_id; 201 int connection_id = parameters_->connection_id;
230 HidConnectionResource* resource = 202 HidConnectionResource* resource =
231 manager_->Get(extension_->id(), connection_id); 203 connection_manager_->Get(extension_->id(), connection_id);
232 if (!resource) { 204 if (!resource) {
233 CompleteWithError(kErrorConnectionNotFound); 205 CompleteWithError(kErrorConnectionNotFound);
234 return; 206 return;
235 } 207 }
236 208
237 scoped_refptr<net::IOBuffer> buffer( 209 scoped_refptr<net::IOBufferWithSize> buffer(
238 new net::WrappedIOBuffer(parameters_->data.c_str())); 210 new net::IOBufferWithSize(parameters_->data.size()));
239 memcpy(buffer->data(), 211 memcpy(buffer->data(),
240 parameters_->data.c_str(), 212 parameters_->data.c_str(),
241 parameters_->data.size()); 213 parameters_->data.size());
242 resource->connection()->Write( 214 resource->connection()->Write(static_cast<uint8_t>(parameters_->report_id),
243 buffer, 215 buffer,
244 parameters_->data.size(), 216 base::Bind(&HidSendFunction::OnFinished, this));
245 base::Bind(&HidSendFunction::OnFinished, this));
246 } 217 }
247 218
248 void HidSendFunction::OnFinished(bool success, size_t bytes) { 219 void HidSendFunction::OnFinished(bool success, size_t bytes) {
249 if (!success) { 220 if (!success) {
250 CompleteWithError(kErrorTransfer); 221 CompleteWithError(kErrorTransfer);
251 return; 222 return;
252 } 223 }
253 AsyncWorkCompleted(); 224 AsyncWorkCompleted();
254 } 225 }
255 226
256 HidReceiveFeatureReportFunction::HidReceiveFeatureReportFunction() {} 227 HidReceiveFeatureReportFunction::HidReceiveFeatureReportFunction() {}
257 228
258 HidReceiveFeatureReportFunction::~HidReceiveFeatureReportFunction() {} 229 HidReceiveFeatureReportFunction::~HidReceiveFeatureReportFunction() {}
259 230
260 bool HidReceiveFeatureReportFunction::Prepare() { 231 bool HidReceiveFeatureReportFunction::Prepare() {
261 parameters_ = hid::ReceiveFeatureReport::Params::Create(*args_); 232 parameters_ = hid::ReceiveFeatureReport::Params::Create(*args_);
262 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 233 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
263 return true; 234 return true;
264 } 235 }
265 236
266 void HidReceiveFeatureReportFunction::AsyncWorkStart() { 237 void HidReceiveFeatureReportFunction::AsyncWorkStart() {
267 int connection_id = parameters_->connection_id; 238 int connection_id = parameters_->connection_id;
268 HidConnectionResource* resource = 239 HidConnectionResource* resource =
269 manager_->Get(extension_->id(), connection_id); 240 connection_manager_->Get(extension_->id(), connection_id);
270 if (!resource) { 241 if (!resource) {
271 CompleteWithError(kErrorConnectionNotFound); 242 CompleteWithError(kErrorConnectionNotFound);
272 return; 243 return;
273 } 244 }
274 buffer_ = new net::IOBuffer(parameters_->size); 245 buffer_ = new net::IOBufferWithSize(parameters_->size);
275 resource->connection()->GetFeatureReport( 246 resource->connection()->GetFeatureReport(
247 static_cast<uint8_t>(parameters_->report_id),
276 buffer_, 248 buffer_,
277 parameters_->size,
278 base::Bind(&HidReceiveFeatureReportFunction::OnFinished, this)); 249 base::Bind(&HidReceiveFeatureReportFunction::OnFinished, this));
279 } 250 }
280 251
281 void HidReceiveFeatureReportFunction::OnFinished(bool success, size_t bytes) { 252 void HidReceiveFeatureReportFunction::OnFinished(bool success, size_t bytes) {
282 if (!success) { 253 if (!success) {
283 CompleteWithError(kErrorTransfer); 254 CompleteWithError(kErrorTransfer);
284 return; 255 return;
285 } 256 }
286 257
287 SetResult(base::BinaryValue::CreateWithCopiedBuffer(buffer_->data(), bytes)); 258 SetResult(base::BinaryValue::CreateWithCopiedBuffer(buffer_->data(), bytes));
288 AsyncWorkCompleted(); 259 AsyncWorkCompleted();
289 } 260 }
290 261
291 HidSendFeatureReportFunction::HidSendFeatureReportFunction() {} 262 HidSendFeatureReportFunction::HidSendFeatureReportFunction() {}
292 263
293 HidSendFeatureReportFunction::~HidSendFeatureReportFunction() {} 264 HidSendFeatureReportFunction::~HidSendFeatureReportFunction() {}
294 265
295 bool HidSendFeatureReportFunction::Prepare() { 266 bool HidSendFeatureReportFunction::Prepare() {
296 parameters_ = hid::SendFeatureReport::Params::Create(*args_); 267 parameters_ = hid::SendFeatureReport::Params::Create(*args_);
297 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 268 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
298 return true; 269 return true;
299 } 270 }
300 271
301 void HidSendFeatureReportFunction::AsyncWorkStart() { 272 void HidSendFeatureReportFunction::AsyncWorkStart() {
302 int connection_id = parameters_->connection_id; 273 int connection_id = parameters_->connection_id;
303 HidConnectionResource* resource = 274 HidConnectionResource* resource =
304 manager_->Get(extension_->id(), connection_id); 275 connection_manager_->Get(extension_->id(), connection_id);
305 if (!resource) { 276 if (!resource) {
306 CompleteWithError(kErrorConnectionNotFound); 277 CompleteWithError(kErrorConnectionNotFound);
307 return; 278 return;
308 } 279 }
309 scoped_refptr<net::IOBuffer> buffer( 280 scoped_refptr<net::IOBufferWithSize> buffer(
310 new net::WrappedIOBuffer(parameters_->data.c_str())); 281 new net::IOBufferWithSize(parameters_->data.size()));
311 resource->connection()->SendFeatureReport( 282 resource->connection()->SendFeatureReport(
283 static_cast<uint8_t>(parameters_->report_id),
312 buffer, 284 buffer,
313 parameters_->data.size(),
314 base::Bind(&HidSendFeatureReportFunction::OnFinished, this)); 285 base::Bind(&HidSendFeatureReportFunction::OnFinished, this));
315 } 286 }
316 287
317 void HidSendFeatureReportFunction::OnFinished(bool success, size_t bytes) { 288 void HidSendFeatureReportFunction::OnFinished(bool success, size_t bytes) {
318 if (!success) { 289 if (!success) {
319 CompleteWithError(kErrorTransfer); 290 CompleteWithError(kErrorTransfer);
320 return; 291 return;
321 } 292 }
322 AsyncWorkCompleted(); 293 AsyncWorkCompleted();
323 } 294 }
324 295
325 } // namespace extensions 296 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698