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

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

Issue 1115213004: Add chrome.hid.getUserSelectedDevices API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Devlin's comments. Created 5 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
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 "extensions/browser/api/hid/hid_api.h" 5 #include "extensions/browser/api/hid/hid_api.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "device/core/device_client.h" 11 #include "device/core/device_client.h"
12 #include "device/hid/hid_connection.h" 12 #include "device/hid/hid_connection.h"
13 #include "device/hid/hid_device_filter.h" 13 #include "device/hid/hid_device_filter.h"
14 #include "device/hid/hid_device_info.h" 14 #include "device/hid/hid_device_info.h"
15 #include "device/hid/hid_service.h" 15 #include "device/hid/hid_service.h"
16 #include "extensions/browser/api/api_resource_manager.h" 16 #include "extensions/browser/api/api_resource_manager.h"
17 #include "extensions/browser/api/device_permissions_prompt.h"
18 #include "extensions/browser/api/extensions_api_client.h"
17 #include "extensions/common/api/hid.h" 19 #include "extensions/common/api/hid.h"
18 #include "net/base/io_buffer.h" 20 #include "net/base/io_buffer.h"
19 21
20 namespace hid = extensions::core_api::hid; 22 namespace hid = extensions::core_api::hid;
21 23
22 using device::HidConnection; 24 using device::HidConnection;
23 using device::HidDeviceFilter; 25 using device::HidDeviceFilter;
24 using device::HidDeviceInfo; 26 using device::HidDeviceInfo;
25 using device::HidService; 27 using device::HidService;
26 28
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 62
61 namespace extensions { 63 namespace extensions {
62 64
63 HidGetDevicesFunction::HidGetDevicesFunction() {} 65 HidGetDevicesFunction::HidGetDevicesFunction() {}
64 66
65 HidGetDevicesFunction::~HidGetDevicesFunction() {} 67 HidGetDevicesFunction::~HidGetDevicesFunction() {}
66 68
67 ExtensionFunction::ResponseAction HidGetDevicesFunction::Run() { 69 ExtensionFunction::ResponseAction HidGetDevicesFunction::Run() {
68 scoped_ptr<core_api::hid::GetDevices::Params> parameters = 70 scoped_ptr<core_api::hid::GetDevices::Params> parameters =
69 hid::GetDevices::Params::Create(*args_); 71 hid::GetDevices::Params::Create(*args_);
70 EXTENSION_FUNCTION_VALIDATE(parameters.get()); 72 EXTENSION_FUNCTION_VALIDATE(parameters);
71 73
72 HidDeviceManager* device_manager = HidDeviceManager::Get(browser_context()); 74 HidDeviceManager* device_manager = HidDeviceManager::Get(browser_context());
73 if (!device_manager) { 75 if (!device_manager) {
74 return RespondNow(Error(kErrorServiceUnavailable)); 76 return RespondNow(Error(kErrorServiceUnavailable));
75 } 77 }
76 78
77 std::vector<HidDeviceFilter> filters; 79 std::vector<HidDeviceFilter> filters;
78 if (parameters->options.filters) { 80 if (parameters->options.filters) {
79 filters.resize(parameters->options.filters->size()); 81 filters.resize(parameters->options.filters->size());
80 for (size_t i = 0; i < parameters->options.filters->size(); ++i) { 82 for (size_t i = 0; i < parameters->options.filters->size(); ++i) {
(...skipping 13 matching lines...) Expand all
94 extension(), filters, 96 extension(), filters,
95 base::Bind(&HidGetDevicesFunction::OnEnumerationComplete, this)); 97 base::Bind(&HidGetDevicesFunction::OnEnumerationComplete, this));
96 return RespondLater(); 98 return RespondLater();
97 } 99 }
98 100
99 void HidGetDevicesFunction::OnEnumerationComplete( 101 void HidGetDevicesFunction::OnEnumerationComplete(
100 scoped_ptr<base::ListValue> devices) { 102 scoped_ptr<base::ListValue> devices) {
101 Respond(OneArgument(devices.release())); 103 Respond(OneArgument(devices.release()));
102 } 104 }
103 105
106 HidGetUserSelectedDevicesFunction::HidGetUserSelectedDevicesFunction() {
107 }
108
109 HidGetUserSelectedDevicesFunction::~HidGetUserSelectedDevicesFunction() {
110 }
111
112 ExtensionFunction::ResponseAction HidGetUserSelectedDevicesFunction::Run() {
113 scoped_ptr<core_api::hid::GetUserSelectedDevices::Params> parameters =
114 hid::GetUserSelectedDevices::Params::Create(*args_);
115 EXTENSION_FUNCTION_VALIDATE(parameters);
116
117 device_manager_ = HidDeviceManager::Get(browser_context());
118 if (!device_manager_) {
119 return RespondNow(Error(kErrorServiceUnavailable));
120 }
121
122 if (!user_gesture()) {
123 return RespondNow(OneArgument(new base::ListValue()));
Devlin 2015/05/06 23:04:28 This looks like it should be an error, not an empt
Reilly Grant (use Gerrit) 2015/05/06 23:48:52 The documented behavior is that this returns an em
Devlin 2015/05/07 20:43:55 Oh, odd. In other places (e.g., the management ap
124 }
125
126 bool multiple = false;
127 std::vector<HidDeviceFilter> filters;
128 if (parameters->options) {
129 multiple = parameters->options->multiple && *parameters->options->multiple;
130 if (parameters->options->filters) {
131 const auto& api_filters = *parameters->options->filters;
132 filters.resize(api_filters.size());
133 for (size_t i = 0; i < api_filters.size(); ++i) {
134 ConvertHidDeviceFilter(api_filters[i], &filters[i]);
135 }
136 }
137 }
138
139 prompt_ = ExtensionsAPIClient::Get()->CreateDevicePermissionsPrompt(
140 GetSenderWebContents());
141 if (!prompt_) {
142 return RespondNow(Error(kErrorServiceUnavailable));
143 }
144
145 prompt_->AskForHidDevices(
146 extension(), browser_context(), multiple, filters,
147 base::Bind(&HidGetUserSelectedDevicesFunction::OnDevicesChosen, this));
148 return RespondLater();
149 }
150
151 void HidGetUserSelectedDevicesFunction::OnDevicesChosen(
152 const std::vector<scoped_refptr<HidDeviceInfo>>& devices) {
153 Respond(OneArgument(device_manager_->GetApiDevicesFromList(devices).Pass()));
154 }
155
104 HidConnectFunction::HidConnectFunction() : connection_manager_(nullptr) { 156 HidConnectFunction::HidConnectFunction() : connection_manager_(nullptr) {
105 } 157 }
106 158
107 HidConnectFunction::~HidConnectFunction() {} 159 HidConnectFunction::~HidConnectFunction() {}
108 160
109 ExtensionFunction::ResponseAction HidConnectFunction::Run() { 161 ExtensionFunction::ResponseAction HidConnectFunction::Run() {
110 scoped_ptr<core_api::hid::Connect::Params> parameters = 162 scoped_ptr<core_api::hid::Connect::Params> parameters =
111 hid::Connect::Params::Create(*args_); 163 hid::Connect::Params::Create(*args_);
112 EXTENSION_FUNCTION_VALIDATE(parameters.get()); 164 EXTENSION_FUNCTION_VALIDATE(parameters);
113 165
114 HidDeviceManager* device_manager = HidDeviceManager::Get(browser_context()); 166 HidDeviceManager* device_manager = HidDeviceManager::Get(browser_context());
115 if (!device_manager) { 167 if (!device_manager) {
116 return RespondNow(Error(kErrorServiceUnavailable)); 168 return RespondNow(Error(kErrorServiceUnavailable));
117 } 169 }
118 170
119 connection_manager_ = 171 connection_manager_ =
120 ApiResourceManager<HidConnectionResource>::Get(browser_context()); 172 ApiResourceManager<HidConnectionResource>::Get(browser_context());
121 if (!connection_manager_) { 173 if (!connection_manager_) {
122 return RespondNow(Error(kErrorServiceUnavailable)); 174 return RespondNow(Error(kErrorServiceUnavailable));
123 } 175 }
124 176
125 scoped_refptr<HidDeviceInfo> device_info = 177 scoped_refptr<HidDeviceInfo> device_info =
126 device_manager->GetDeviceInfo(parameters->device_id); 178 device_manager->GetDeviceInfo(parameters->device_id);
127 if (!device_info) { 179 if (!device_info) {
128 return RespondNow(Error(kErrorInvalidDeviceId)); 180 return RespondNow(Error(kErrorInvalidDeviceId));
129 } 181 }
130 182
131 if (!HidDeviceManager::HasPermission(extension(), device_info)) { 183 if (!device_manager->HasPermission(extension(), device_info, true)) {
132 return RespondNow(Error(kErrorPermissionDenied)); 184 return RespondNow(Error(kErrorPermissionDenied));
133 } 185 }
134 186
135 HidService* hid_service = device::DeviceClient::Get()->GetHidService(); 187 HidService* hid_service = device::DeviceClient::Get()->GetHidService();
136 if (!hid_service) { 188 if (!hid_service) {
137 return RespondNow(Error(kErrorServiceUnavailable)); 189 return RespondNow(Error(kErrorServiceUnavailable));
138 } 190 }
139 191
140 hid_service->Connect( 192 hid_service->Connect(
141 device_info->device_id(), 193 device_info->device_id(),
142 base::Bind(&HidConnectFunction::OnConnectComplete, this)); 194 base::Bind(&HidConnectFunction::OnConnectComplete, this));
143 return RespondLater(); 195 return RespondLater();
144 } 196 }
145 197
146 void HidConnectFunction::OnConnectComplete( 198 void HidConnectFunction::OnConnectComplete(
147 scoped_refptr<HidConnection> connection) { 199 scoped_refptr<HidConnection> connection) {
148 if (!connection.get()) { 200 if (!connection) {
149 Respond(Error(kErrorFailedToOpenDevice)); 201 Respond(Error(kErrorFailedToOpenDevice));
150 return; 202 return;
151 } 203 }
152 204
153 DCHECK(connection_manager_); 205 DCHECK(connection_manager_);
154 int connection_id = connection_manager_->Add( 206 int connection_id = connection_manager_->Add(
155 new HidConnectionResource(extension_id(), connection)); 207 new HidConnectionResource(extension_id(), connection));
156 Respond(OneArgument(PopulateHidConnection(connection_id, connection))); 208 Respond(OneArgument(PopulateHidConnection(connection_id, connection)));
157 } 209 }
158 210
159 HidDisconnectFunction::HidDisconnectFunction() {} 211 HidDisconnectFunction::HidDisconnectFunction() {}
160 212
161 HidDisconnectFunction::~HidDisconnectFunction() {} 213 HidDisconnectFunction::~HidDisconnectFunction() {}
162 214
163 ExtensionFunction::ResponseAction HidDisconnectFunction::Run() { 215 ExtensionFunction::ResponseAction HidDisconnectFunction::Run() {
164 scoped_ptr<core_api::hid::Disconnect::Params> parameters = 216 scoped_ptr<core_api::hid::Disconnect::Params> parameters =
165 hid::Disconnect::Params::Create(*args_); 217 hid::Disconnect::Params::Create(*args_);
166 EXTENSION_FUNCTION_VALIDATE(parameters.get()); 218 EXTENSION_FUNCTION_VALIDATE(parameters);
167 219
168 ApiResourceManager<HidConnectionResource>* connection_manager = 220 ApiResourceManager<HidConnectionResource>* connection_manager =
169 ApiResourceManager<HidConnectionResource>::Get(browser_context()); 221 ApiResourceManager<HidConnectionResource>::Get(browser_context());
170 if (!connection_manager) { 222 if (!connection_manager) {
171 return RespondNow(Error(kErrorServiceUnavailable)); 223 return RespondNow(Error(kErrorServiceUnavailable));
172 } 224 }
173 225
174 int connection_id = parameters->connection_id; 226 int connection_id = parameters->connection_id;
175 HidConnectionResource* resource = 227 HidConnectionResource* resource =
176 connection_manager->Get(extension_id(), connection_id); 228 connection_manager->Get(extension_id(), connection_id);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 StartWork(resource->connection().get()); 260 StartWork(resource->connection().get());
209 return RespondLater(); 261 return RespondLater();
210 } 262 }
211 263
212 HidReceiveFunction::HidReceiveFunction() {} 264 HidReceiveFunction::HidReceiveFunction() {}
213 265
214 HidReceiveFunction::~HidReceiveFunction() {} 266 HidReceiveFunction::~HidReceiveFunction() {}
215 267
216 bool HidReceiveFunction::ValidateParameters() { 268 bool HidReceiveFunction::ValidateParameters() {
217 parameters_ = hid::Receive::Params::Create(*args_); 269 parameters_ = hid::Receive::Params::Create(*args_);
218 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 270 EXTENSION_FUNCTION_VALIDATE(parameters_);
219 set_connection_id(parameters_->connection_id); 271 set_connection_id(parameters_->connection_id);
220 return true; 272 return true;
221 } 273 }
222 274
223 void HidReceiveFunction::StartWork(HidConnection* connection) { 275 void HidReceiveFunction::StartWork(HidConnection* connection) {
224 connection->Read(base::Bind(&HidReceiveFunction::OnFinished, this)); 276 connection->Read(base::Bind(&HidReceiveFunction::OnFinished, this));
225 } 277 }
226 278
227 void HidReceiveFunction::OnFinished(bool success, 279 void HidReceiveFunction::OnFinished(bool success,
228 scoped_refptr<net::IOBuffer> buffer, 280 scoped_refptr<net::IOBuffer> buffer,
229 size_t size) { 281 size_t size) {
230 if (success) { 282 if (success) {
231 DCHECK_GE(size, 1u); 283 DCHECK_GE(size, 1u);
232 int report_id = reinterpret_cast<uint8_t*>(buffer->data())[0]; 284 int report_id = reinterpret_cast<uint8_t*>(buffer->data())[0];
233 285
234 Respond(TwoArguments(new base::FundamentalValue(report_id), 286 Respond(TwoArguments(new base::FundamentalValue(report_id),
235 base::BinaryValue::CreateWithCopiedBuffer( 287 base::BinaryValue::CreateWithCopiedBuffer(
236 buffer->data() + 1, size - 1))); 288 buffer->data() + 1, size - 1)));
237 } else { 289 } else {
238 Respond(Error(kErrorTransfer)); 290 Respond(Error(kErrorTransfer));
239 } 291 }
240 } 292 }
241 293
242 HidSendFunction::HidSendFunction() {} 294 HidSendFunction::HidSendFunction() {}
243 295
244 HidSendFunction::~HidSendFunction() {} 296 HidSendFunction::~HidSendFunction() {}
245 297
246 bool HidSendFunction::ValidateParameters() { 298 bool HidSendFunction::ValidateParameters() {
247 parameters_ = hid::Send::Params::Create(*args_); 299 parameters_ = hid::Send::Params::Create(*args_);
248 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 300 EXTENSION_FUNCTION_VALIDATE(parameters_);
249 set_connection_id(parameters_->connection_id); 301 set_connection_id(parameters_->connection_id);
250 return true; 302 return true;
251 } 303 }
252 304
253 void HidSendFunction::StartWork(HidConnection* connection) { 305 void HidSendFunction::StartWork(HidConnection* connection) {
254 scoped_refptr<net::IOBufferWithSize> buffer( 306 scoped_refptr<net::IOBufferWithSize> buffer(
255 new net::IOBufferWithSize(parameters_->data.size() + 1)); 307 new net::IOBufferWithSize(parameters_->data.size() + 1));
256 buffer->data()[0] = static_cast<uint8_t>(parameters_->report_id); 308 buffer->data()[0] = static_cast<uint8_t>(parameters_->report_id);
257 memcpy(buffer->data() + 1, parameters_->data.data(), 309 memcpy(buffer->data() + 1, parameters_->data.data(),
258 parameters_->data.size()); 310 parameters_->data.size());
259 connection->Write(buffer, buffer->size(), 311 connection->Write(buffer, buffer->size(),
260 base::Bind(&HidSendFunction::OnFinished, this)); 312 base::Bind(&HidSendFunction::OnFinished, this));
261 } 313 }
262 314
263 void HidSendFunction::OnFinished(bool success) { 315 void HidSendFunction::OnFinished(bool success) {
264 if (success) { 316 if (success) {
265 Respond(NoArguments()); 317 Respond(NoArguments());
266 } else { 318 } else {
267 Respond(Error(kErrorTransfer)); 319 Respond(Error(kErrorTransfer));
268 } 320 }
269 } 321 }
270 322
271 HidReceiveFeatureReportFunction::HidReceiveFeatureReportFunction() {} 323 HidReceiveFeatureReportFunction::HidReceiveFeatureReportFunction() {}
272 324
273 HidReceiveFeatureReportFunction::~HidReceiveFeatureReportFunction() {} 325 HidReceiveFeatureReportFunction::~HidReceiveFeatureReportFunction() {}
274 326
275 bool HidReceiveFeatureReportFunction::ValidateParameters() { 327 bool HidReceiveFeatureReportFunction::ValidateParameters() {
276 parameters_ = hid::ReceiveFeatureReport::Params::Create(*args_); 328 parameters_ = hid::ReceiveFeatureReport::Params::Create(*args_);
277 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 329 EXTENSION_FUNCTION_VALIDATE(parameters_);
278 set_connection_id(parameters_->connection_id); 330 set_connection_id(parameters_->connection_id);
279 return true; 331 return true;
280 } 332 }
281 333
282 void HidReceiveFeatureReportFunction::StartWork(HidConnection* connection) { 334 void HidReceiveFeatureReportFunction::StartWork(HidConnection* connection) {
283 connection->GetFeatureReport( 335 connection->GetFeatureReport(
284 static_cast<uint8_t>(parameters_->report_id), 336 static_cast<uint8_t>(parameters_->report_id),
285 base::Bind(&HidReceiveFeatureReportFunction::OnFinished, this)); 337 base::Bind(&HidReceiveFeatureReportFunction::OnFinished, this));
286 } 338 }
287 339
288 void HidReceiveFeatureReportFunction::OnFinished( 340 void HidReceiveFeatureReportFunction::OnFinished(
289 bool success, 341 bool success,
290 scoped_refptr<net::IOBuffer> buffer, 342 scoped_refptr<net::IOBuffer> buffer,
291 size_t size) { 343 size_t size) {
292 if (success) { 344 if (success) {
293 Respond(OneArgument( 345 Respond(OneArgument(
294 base::BinaryValue::CreateWithCopiedBuffer(buffer->data(), size))); 346 base::BinaryValue::CreateWithCopiedBuffer(buffer->data(), size)));
295 } else { 347 } else {
296 Respond(Error(kErrorTransfer)); 348 Respond(Error(kErrorTransfer));
297 } 349 }
298 } 350 }
299 351
300 HidSendFeatureReportFunction::HidSendFeatureReportFunction() {} 352 HidSendFeatureReportFunction::HidSendFeatureReportFunction() {}
301 353
302 HidSendFeatureReportFunction::~HidSendFeatureReportFunction() {} 354 HidSendFeatureReportFunction::~HidSendFeatureReportFunction() {}
303 355
304 bool HidSendFeatureReportFunction::ValidateParameters() { 356 bool HidSendFeatureReportFunction::ValidateParameters() {
305 parameters_ = hid::SendFeatureReport::Params::Create(*args_); 357 parameters_ = hid::SendFeatureReport::Params::Create(*args_);
306 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 358 EXTENSION_FUNCTION_VALIDATE(parameters_);
307 set_connection_id(parameters_->connection_id); 359 set_connection_id(parameters_->connection_id);
308 return true; 360 return true;
309 } 361 }
310 362
311 void HidSendFeatureReportFunction::StartWork(HidConnection* connection) { 363 void HidSendFeatureReportFunction::StartWork(HidConnection* connection) {
312 scoped_refptr<net::IOBufferWithSize> buffer( 364 scoped_refptr<net::IOBufferWithSize> buffer(
313 new net::IOBufferWithSize(parameters_->data.size() + 1)); 365 new net::IOBufferWithSize(parameters_->data.size() + 1));
314 buffer->data()[0] = static_cast<uint8_t>(parameters_->report_id); 366 buffer->data()[0] = static_cast<uint8_t>(parameters_->report_id);
315 memcpy(buffer->data() + 1, vector_as_array(&parameters_->data), 367 memcpy(buffer->data() + 1, vector_as_array(&parameters_->data),
316 parameters_->data.size()); 368 parameters_->data.size());
317 connection->SendFeatureReport( 369 connection->SendFeatureReport(
318 buffer, buffer->size(), 370 buffer, buffer->size(),
319 base::Bind(&HidSendFeatureReportFunction::OnFinished, this)); 371 base::Bind(&HidSendFeatureReportFunction::OnFinished, this));
320 } 372 }
321 373
322 void HidSendFeatureReportFunction::OnFinished(bool success) { 374 void HidSendFeatureReportFunction::OnFinished(bool success) {
323 if (success) { 375 if (success) {
324 Respond(NoArguments()); 376 Respond(NoArguments());
325 } else { 377 } else {
326 Respond(Error(kErrorTransfer)); 378 Respond(Error(kErrorTransfer));
327 } 379 }
328 } 380 }
329 381
330 } // namespace extensions 382 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698