| OLD | NEW |
| 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 "device/hid/hid_connection.h" | 10 #include "device/hid/hid_connection.h" |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 void HidReceiveFunction::AsyncWorkStart() { | 176 void HidReceiveFunction::AsyncWorkStart() { |
| 177 int connection_id = parameters_->connection_id; | 177 int connection_id = parameters_->connection_id; |
| 178 HidConnectionResource* resource = | 178 HidConnectionResource* resource = |
| 179 connection_manager_->Get(extension_->id(), connection_id); | 179 connection_manager_->Get(extension_->id(), connection_id); |
| 180 if (!resource) { | 180 if (!resource) { |
| 181 CompleteWithError(kErrorConnectionNotFound); | 181 CompleteWithError(kErrorConnectionNotFound); |
| 182 return; | 182 return; |
| 183 } | 183 } |
| 184 | 184 |
| 185 scoped_refptr<device::HidConnection> connection = resource->connection(); | 185 scoped_refptr<device::HidConnection> connection = resource->connection(); |
| 186 has_report_id_ = connection->device_info().has_report_id; | 186 connection->Read(base::Bind(&HidReceiveFunction::OnFinished, this)); |
| 187 int size = connection->device_info().max_input_report_size; | |
| 188 if (has_report_id_) { | |
| 189 ++size; // One byte at the beginning of the buffer for the report ID. | |
| 190 } | |
| 191 buffer_ = new net::IOBufferWithSize(size); | |
| 192 connection->Read(buffer_, base::Bind(&HidReceiveFunction::OnFinished, this)); | |
| 193 } | 187 } |
| 194 | 188 |
| 195 void HidReceiveFunction::OnFinished(bool success, size_t bytes) { | 189 void HidReceiveFunction::OnFinished(bool success, |
| 190 scoped_refptr<net::IOBuffer> buffer, |
| 191 size_t size) { |
| 196 if (!success) { | 192 if (!success) { |
| 197 CompleteWithError(kErrorTransfer); | 193 CompleteWithError(kErrorTransfer); |
| 198 return; | 194 return; |
| 199 } | 195 } |
| 200 | 196 |
| 201 int report_id = 0; | 197 DCHECK_GE(size, 1u); |
| 202 const char* data = buffer_->data(); | 198 int report_id = reinterpret_cast<uint8_t*>(buffer->data())[0]; |
| 203 if (has_report_id_) { | |
| 204 if (bytes < 1) { | |
| 205 CompleteWithError(kErrorTransfer); | |
| 206 return; | |
| 207 } | |
| 208 report_id = data[0]; | |
| 209 data++; | |
| 210 bytes--; | |
| 211 } | |
| 212 | 199 |
| 213 scoped_ptr<base::ListValue> result(new base::ListValue()); | 200 scoped_ptr<base::ListValue> result(new base::ListValue()); |
| 214 result->Append(new base::FundamentalValue(report_id)); | 201 result->Append(new base::FundamentalValue(report_id)); |
| 215 result->Append(base::BinaryValue::CreateWithCopiedBuffer(data, bytes)); | 202 result->Append( |
| 203 base::BinaryValue::CreateWithCopiedBuffer(buffer->data() + 1, size - 1)); |
| 216 SetResultList(result.Pass()); | 204 SetResultList(result.Pass()); |
| 217 AsyncWorkCompleted(); | 205 AsyncWorkCompleted(); |
| 218 } | 206 } |
| 219 | 207 |
| 220 HidSendFunction::HidSendFunction() {} | 208 HidSendFunction::HidSendFunction() {} |
| 221 | 209 |
| 222 HidSendFunction::~HidSendFunction() {} | 210 HidSendFunction::~HidSendFunction() {} |
| 223 | 211 |
| 224 bool HidSendFunction::Prepare() { | 212 bool HidSendFunction::Prepare() { |
| 225 parameters_ = hid::Send::Params::Create(*args_); | 213 parameters_ = hid::Send::Params::Create(*args_); |
| 226 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 214 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 227 return true; | 215 return true; |
| 228 } | 216 } |
| 229 | 217 |
| 230 void HidSendFunction::AsyncWorkStart() { | 218 void HidSendFunction::AsyncWorkStart() { |
| 231 int connection_id = parameters_->connection_id; | 219 int connection_id = parameters_->connection_id; |
| 232 HidConnectionResource* resource = | 220 HidConnectionResource* resource = |
| 233 connection_manager_->Get(extension_->id(), connection_id); | 221 connection_manager_->Get(extension_->id(), connection_id); |
| 234 if (!resource) { | 222 if (!resource) { |
| 235 CompleteWithError(kErrorConnectionNotFound); | 223 CompleteWithError(kErrorConnectionNotFound); |
| 236 return; | 224 return; |
| 237 } | 225 } |
| 238 | 226 |
| 239 scoped_refptr<net::IOBufferWithSize> buffer( | 227 scoped_refptr<net::IOBufferWithSize> buffer( |
| 240 new net::IOBufferWithSize(parameters_->data.size())); | 228 new net::IOBufferWithSize(parameters_->data.size() + 1)); |
| 241 memcpy(buffer->data(), parameters_->data.c_str(), parameters_->data.size()); | 229 buffer->data()[0] = static_cast<uint8_t>(parameters_->report_id); |
| 242 resource->connection()->Write(static_cast<uint8_t>(parameters_->report_id), | 230 memcpy( |
| 243 buffer, | 231 buffer->data() + 1, parameters_->data.c_str(), parameters_->data.size()); |
| 244 base::Bind(&HidSendFunction::OnFinished, this)); | 232 resource->connection()->Write( |
| 233 buffer, buffer->size(), base::Bind(&HidSendFunction::OnFinished, this)); |
| 245 } | 234 } |
| 246 | 235 |
| 247 void HidSendFunction::OnFinished(bool success, size_t bytes) { | 236 void HidSendFunction::OnFinished(bool success) { |
| 248 if (!success) { | 237 if (!success) { |
| 249 CompleteWithError(kErrorTransfer); | 238 CompleteWithError(kErrorTransfer); |
| 250 return; | 239 return; |
| 251 } | 240 } |
| 252 AsyncWorkCompleted(); | 241 AsyncWorkCompleted(); |
| 253 } | 242 } |
| 254 | 243 |
| 255 HidReceiveFeatureReportFunction::HidReceiveFeatureReportFunction() {} | 244 HidReceiveFeatureReportFunction::HidReceiveFeatureReportFunction() {} |
| 256 | 245 |
| 257 HidReceiveFeatureReportFunction::~HidReceiveFeatureReportFunction() {} | 246 HidReceiveFeatureReportFunction::~HidReceiveFeatureReportFunction() {} |
| 258 | 247 |
| 259 bool HidReceiveFeatureReportFunction::Prepare() { | 248 bool HidReceiveFeatureReportFunction::Prepare() { |
| 260 parameters_ = hid::ReceiveFeatureReport::Params::Create(*args_); | 249 parameters_ = hid::ReceiveFeatureReport::Params::Create(*args_); |
| 261 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 250 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 262 return true; | 251 return true; |
| 263 } | 252 } |
| 264 | 253 |
| 265 void HidReceiveFeatureReportFunction::AsyncWorkStart() { | 254 void HidReceiveFeatureReportFunction::AsyncWorkStart() { |
| 266 int connection_id = parameters_->connection_id; | 255 int connection_id = parameters_->connection_id; |
| 267 HidConnectionResource* resource = | 256 HidConnectionResource* resource = |
| 268 connection_manager_->Get(extension_->id(), connection_id); | 257 connection_manager_->Get(extension_->id(), connection_id); |
| 269 if (!resource) { | 258 if (!resource) { |
| 270 CompleteWithError(kErrorConnectionNotFound); | 259 CompleteWithError(kErrorConnectionNotFound); |
| 271 return; | 260 return; |
| 272 } | 261 } |
| 273 | 262 |
| 274 scoped_refptr<device::HidConnection> connection = resource->connection(); | 263 scoped_refptr<device::HidConnection> connection = resource->connection(); |
| 275 const int size = connection->device_info().max_feature_report_size; | |
| 276 buffer_ = new net::IOBufferWithSize(size); | |
| 277 connection->GetFeatureReport( | 264 connection->GetFeatureReport( |
| 278 static_cast<uint8_t>(parameters_->report_id), | 265 static_cast<uint8_t>(parameters_->report_id), |
| 279 buffer_, | |
| 280 base::Bind(&HidReceiveFeatureReportFunction::OnFinished, this)); | 266 base::Bind(&HidReceiveFeatureReportFunction::OnFinished, this)); |
| 281 } | 267 } |
| 282 | 268 |
| 283 void HidReceiveFeatureReportFunction::OnFinished(bool success, size_t bytes) { | 269 void HidReceiveFeatureReportFunction::OnFinished( |
| 270 bool success, |
| 271 scoped_refptr<net::IOBuffer> buffer, |
| 272 size_t size) { |
| 284 if (!success) { | 273 if (!success) { |
| 285 CompleteWithError(kErrorTransfer); | 274 CompleteWithError(kErrorTransfer); |
| 286 return; | 275 return; |
| 287 } | 276 } |
| 288 | 277 |
| 289 SetResult(base::BinaryValue::CreateWithCopiedBuffer(buffer_->data(), bytes)); | 278 SetResult(base::BinaryValue::CreateWithCopiedBuffer(buffer->data(), size)); |
| 290 AsyncWorkCompleted(); | 279 AsyncWorkCompleted(); |
| 291 } | 280 } |
| 292 | 281 |
| 293 HidSendFeatureReportFunction::HidSendFeatureReportFunction() {} | 282 HidSendFeatureReportFunction::HidSendFeatureReportFunction() {} |
| 294 | 283 |
| 295 HidSendFeatureReportFunction::~HidSendFeatureReportFunction() {} | 284 HidSendFeatureReportFunction::~HidSendFeatureReportFunction() {} |
| 296 | 285 |
| 297 bool HidSendFeatureReportFunction::Prepare() { | 286 bool HidSendFeatureReportFunction::Prepare() { |
| 298 parameters_ = hid::SendFeatureReport::Params::Create(*args_); | 287 parameters_ = hid::SendFeatureReport::Params::Create(*args_); |
| 299 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 288 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 300 return true; | 289 return true; |
| 301 } | 290 } |
| 302 | 291 |
| 303 void HidSendFeatureReportFunction::AsyncWorkStart() { | 292 void HidSendFeatureReportFunction::AsyncWorkStart() { |
| 304 int connection_id = parameters_->connection_id; | 293 int connection_id = parameters_->connection_id; |
| 305 HidConnectionResource* resource = | 294 HidConnectionResource* resource = |
| 306 connection_manager_->Get(extension_->id(), connection_id); | 295 connection_manager_->Get(extension_->id(), connection_id); |
| 307 if (!resource) { | 296 if (!resource) { |
| 308 CompleteWithError(kErrorConnectionNotFound); | 297 CompleteWithError(kErrorConnectionNotFound); |
| 309 return; | 298 return; |
| 310 } | 299 } |
| 300 |
| 311 scoped_refptr<net::IOBufferWithSize> buffer( | 301 scoped_refptr<net::IOBufferWithSize> buffer( |
| 312 new net::IOBufferWithSize(parameters_->data.size())); | 302 new net::IOBufferWithSize(parameters_->data.size() + 1)); |
| 313 memcpy(buffer->data(), parameters_->data.c_str(), parameters_->data.size()); | 303 buffer->data()[0] = static_cast<uint8_t>(parameters_->report_id); |
| 304 memcpy( |
| 305 buffer->data() + 1, parameters_->data.c_str(), parameters_->data.size()); |
| 314 resource->connection()->SendFeatureReport( | 306 resource->connection()->SendFeatureReport( |
| 315 static_cast<uint8_t>(parameters_->report_id), | |
| 316 buffer, | 307 buffer, |
| 308 buffer->size(), |
| 317 base::Bind(&HidSendFeatureReportFunction::OnFinished, this)); | 309 base::Bind(&HidSendFeatureReportFunction::OnFinished, this)); |
| 318 } | 310 } |
| 319 | 311 |
| 320 void HidSendFeatureReportFunction::OnFinished(bool success, size_t bytes) { | 312 void HidSendFeatureReportFunction::OnFinished(bool success) { |
| 321 if (!success) { | 313 if (!success) { |
| 322 CompleteWithError(kErrorTransfer); | 314 CompleteWithError(kErrorTransfer); |
| 323 return; | 315 return; |
| 324 } | 316 } |
| 325 AsyncWorkCompleted(); | 317 AsyncWorkCompleted(); |
| 326 } | 318 } |
| 327 | 319 |
| 328 } // namespace extensions | 320 } // namespace extensions |
| OLD | NEW |