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