| 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/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() { return error_.empty(); } |
| 67 | 60 |
| 68 HidConnectionResource* HidAsyncApiFunction::GetHidConnectionResource( | 61 HidConnectionResource* HidAsyncApiFunction::GetHidConnectionResource( |
| 69 int api_resource_id) { | 62 int api_resource_id) { |
| 70 return manager_->Get(extension_->id(), api_resource_id); | 63 return connection_manager_->Get(extension_->id(), api_resource_id); |
| 71 } | 64 } |
| 72 | 65 |
| 73 void HidAsyncApiFunction::RemoveHidConnectionResource(int api_resource_id) { | 66 void HidAsyncApiFunction::RemoveHidConnectionResource(int api_resource_id) { |
| 74 manager_->Remove(extension_->id(), api_resource_id); | 67 connection_manager_->Remove(extension_->id(), api_resource_id); |
| 75 } | 68 } |
| 76 | 69 |
| 77 void HidAsyncApiFunction::CompleteWithError(const std::string& error) { | 70 void HidAsyncApiFunction::CompleteWithError(const std::string& error) { |
| 78 SetError(error); | 71 SetError(error); |
| 79 AsyncWorkCompleted(); | 72 AsyncWorkCompleted(); |
| 80 } | 73 } |
| 81 | 74 |
| 82 HidGetDevicesFunction::HidGetDevicesFunction() {} | 75 HidGetDevicesFunction::HidGetDevicesFunction() {} |
| 83 | 76 |
| 84 HidGetDevicesFunction::~HidGetDevicesFunction() {} | 77 HidGetDevicesFunction::~HidGetDevicesFunction() {} |
| 85 | 78 |
| 86 bool HidGetDevicesFunction::Prepare() { | 79 bool HidGetDevicesFunction::Prepare() { |
| 87 parameters_ = hid::GetDevices::Params::Create(*args_); | 80 parameters_ = hid::GetDevices::Params::Create(*args_); |
| 88 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 81 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 89 return true; | 82 return true; |
| 90 } | 83 } |
| 91 | 84 |
| 92 void HidGetDevicesFunction::AsyncWorkStart() { | 85 void HidGetDevicesFunction::AsyncWorkStart() { |
| 93 const uint16_t vendor_id = parameters_->options.vendor_id; | 86 const uint16_t vendor_id = parameters_->options.vendor_id; |
| 94 const uint16_t product_id = parameters_->options.product_id; | 87 const uint16_t product_id = parameters_->options.product_id; |
| 95 UsbDevicePermission::CheckParam param( | 88 UsbDevicePermission::CheckParam param( |
| 96 vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE); | 89 vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE); |
| 97 if (!PermissionsData::CheckAPIPermissionWithParam( | 90 if (!PermissionsData::CheckAPIPermissionWithParam( |
| 98 GetExtension(), APIPermission::kUsbDevice, ¶m)) { | 91 GetExtension(), APIPermission::kUsbDevice, ¶m)) { |
| 99 LOG(WARNING) << "Insufficient permissions to access device."; | 92 LOG(WARNING) << "Insufficient permissions to access device."; |
| 100 CompleteWithError(kErrorPermissionDenied); | 93 CompleteWithError(kErrorPermissionDenied); |
| 101 return; | 94 return; |
| 102 } | 95 } |
| 103 | 96 |
| 104 HidService* service = HidService::GetInstance(); | 97 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(); | 98 AsyncWorkCompleted(); |
| 121 } | 99 } |
| 122 | 100 |
| 123 HidConnectFunction::HidConnectFunction() {} | 101 HidConnectFunction::HidConnectFunction() {} |
| 124 | 102 |
| 125 HidConnectFunction::~HidConnectFunction() {} | 103 HidConnectFunction::~HidConnectFunction() {} |
| 126 | 104 |
| 127 bool HidConnectFunction::Prepare() { | 105 bool HidConnectFunction::Prepare() { |
| 128 parameters_ = hid::Connect::Params::Create(*args_); | 106 parameters_ = hid::Connect::Params::Create(*args_); |
| 129 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 107 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 130 return true; | 108 return true; |
| 131 } | 109 } |
| 132 | 110 |
| 133 void HidConnectFunction::AsyncWorkStart() { | 111 void HidConnectFunction::AsyncWorkStart() { |
| 134 HidService* service = HidService::GetInstance(); | 112 device::HidDeviceInfo device_info; |
| 135 if (!service) { | 113 if (!device_manager_->GetDeviceInfo(parameters_->device_id, &device_info)) { |
| 136 CompleteWithError(kErrorServiceFailed); | 114 CompleteWithError(kErrorInvalidDeviceId); |
| 137 return; | 115 return; |
| 138 } | 116 } |
| 139 HidDeviceInfo device; | 117 HidService* hid_service = HidService::GetInstance(); |
| 140 if (!service->GetInfo(parameters_->device_info.path, &device)) { | 118 DCHECK(hid_service); |
| 141 CompleteWithError(kErrorDeviceNotFound); | 119 scoped_refptr<HidConnection> connection = |
| 142 return; | 120 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) { | 121 if (!connection) { |
| 151 CompleteWithError(kErrorFailedToOpenDevice); | 122 CompleteWithError(kErrorFailedToOpenDevice); |
| 152 return; | 123 return; |
| 153 } | 124 } |
| 154 int connection_id = | 125 int connection_id = connection_manager_->Add( |
| 155 manager_->Add(new HidConnectionResource(extension_->id(), connection)); | 126 new HidConnectionResource(extension_->id(), connection)); |
| 156 SetResult(PopulateHidConnection(connection_id, connection)); | 127 SetResult(PopulateHidConnection(connection_id, connection)); |
| 157 AsyncWorkCompleted(); | 128 AsyncWorkCompleted(); |
| 158 } | 129 } |
| 159 | 130 |
| 160 HidDisconnectFunction::HidDisconnectFunction() {} | 131 HidDisconnectFunction::HidDisconnectFunction() {} |
| 161 | 132 |
| 162 HidDisconnectFunction::~HidDisconnectFunction() {} | 133 HidDisconnectFunction::~HidDisconnectFunction() {} |
| 163 | 134 |
| 164 bool HidDisconnectFunction::Prepare() { | 135 bool HidDisconnectFunction::Prepare() { |
| 165 parameters_ = hid::Disconnect::Params::Create(*args_); | 136 parameters_ = hid::Disconnect::Params::Create(*args_); |
| 166 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 137 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 167 return true; | 138 return true; |
| 168 } | 139 } |
| 169 | 140 |
| 170 void HidDisconnectFunction::AsyncWorkStart() { | 141 void HidDisconnectFunction::AsyncWorkStart() { |
| 171 int connection_id = parameters_->connection_id; | 142 int connection_id = parameters_->connection_id; |
| 172 HidConnectionResource* resource = | 143 HidConnectionResource* resource = |
| 173 manager_->Get(extension_->id(), connection_id); | 144 connection_manager_->Get(extension_->id(), connection_id); |
| 174 if (!resource) { | 145 if (!resource) { |
| 175 CompleteWithError(kErrorConnectionNotFound); | 146 CompleteWithError(kErrorConnectionNotFound); |
| 176 return; | 147 return; |
| 177 } | 148 } |
| 178 manager_->Remove(extension_->id(), connection_id); | 149 connection_manager_->Remove(extension_->id(), connection_id); |
| 179 AsyncWorkCompleted(); | 150 AsyncWorkCompleted(); |
| 180 } | 151 } |
| 181 | 152 |
| 182 HidReceiveFunction::HidReceiveFunction() {} | 153 HidReceiveFunction::HidReceiveFunction() {} |
| 183 | 154 |
| 184 HidReceiveFunction::~HidReceiveFunction() {} | 155 HidReceiveFunction::~HidReceiveFunction() {} |
| 185 | 156 |
| 186 bool HidReceiveFunction::Prepare() { | 157 bool HidReceiveFunction::Prepare() { |
| 187 parameters_ = hid::Receive::Params::Create(*args_); | 158 parameters_ = hid::Receive::Params::Create(*args_); |
| 188 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 159 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 189 return true; | 160 return true; |
| 190 } | 161 } |
| 191 | 162 |
| 192 void HidReceiveFunction::AsyncWorkStart() { | 163 void HidReceiveFunction::AsyncWorkStart() { |
| 193 int connection_id = parameters_->connection_id; | 164 int connection_id = parameters_->connection_id; |
| 194 HidConnectionResource* resource = | 165 HidConnectionResource* resource = |
| 195 manager_->Get(extension_->id(), connection_id); | 166 connection_manager_->Get(extension_->id(), connection_id); |
| 196 if (!resource) { | 167 if (!resource) { |
| 197 CompleteWithError(kErrorConnectionNotFound); | 168 CompleteWithError(kErrorConnectionNotFound); |
| 198 return; | 169 return; |
| 199 } | 170 } |
| 200 | 171 |
| 201 buffer_ = new net::IOBuffer(parameters_->size); | 172 buffer_ = new net::IOBufferWithSize(parameters_->size); |
| 202 resource->connection()->Read( | 173 resource->connection()->Read( |
| 203 buffer_, | 174 buffer_, |
| 204 parameters_->size, | |
| 205 base::Bind(&HidReceiveFunction::OnFinished, this)); | 175 base::Bind(&HidReceiveFunction::OnFinished, this)); |
| 206 } | 176 } |
| 207 | 177 |
| 208 void HidReceiveFunction::OnFinished(bool success, size_t bytes) { | 178 void HidReceiveFunction::OnFinished(bool success, size_t bytes) { |
| 209 if (!success) { | 179 if (!success) { |
| 210 CompleteWithError(kErrorTransfer); | 180 CompleteWithError(kErrorTransfer); |
| 211 return; | 181 return; |
| 212 } | 182 } |
| 213 | 183 |
| 214 SetResult(base::BinaryValue::CreateWithCopiedBuffer(buffer_->data(), bytes)); | 184 SetResult(base::BinaryValue::CreateWithCopiedBuffer(buffer_->data(), bytes)); |
| 215 AsyncWorkCompleted(); | 185 AsyncWorkCompleted(); |
| 216 } | 186 } |
| 217 | 187 |
| 218 HidSendFunction::HidSendFunction() {} | 188 HidSendFunction::HidSendFunction() {} |
| 219 | 189 |
| 220 HidSendFunction::~HidSendFunction() {} | 190 HidSendFunction::~HidSendFunction() {} |
| 221 | 191 |
| 222 bool HidSendFunction::Prepare() { | 192 bool HidSendFunction::Prepare() { |
| 223 parameters_ = hid::Send::Params::Create(*args_); | 193 parameters_ = hid::Send::Params::Create(*args_); |
| 224 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 194 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 225 return true; | 195 return true; |
| 226 } | 196 } |
| 227 | 197 |
| 228 void HidSendFunction::AsyncWorkStart() { | 198 void HidSendFunction::AsyncWorkStart() { |
| 229 int connection_id = parameters_->connection_id; | 199 int connection_id = parameters_->connection_id; |
| 230 HidConnectionResource* resource = | 200 HidConnectionResource* resource = |
| 231 manager_->Get(extension_->id(), connection_id); | 201 connection_manager_->Get(extension_->id(), connection_id); |
| 232 if (!resource) { | 202 if (!resource) { |
| 233 CompleteWithError(kErrorConnectionNotFound); | 203 CompleteWithError(kErrorConnectionNotFound); |
| 234 return; | 204 return; |
| 235 } | 205 } |
| 236 | 206 |
| 237 scoped_refptr<net::IOBuffer> buffer( | 207 scoped_refptr<net::IOBufferWithSize> buffer( |
| 238 new net::WrappedIOBuffer(parameters_->data.c_str())); | 208 new net::IOBufferWithSize(parameters_->data.size())); |
| 239 memcpy(buffer->data(), | 209 memcpy(buffer->data(), |
| 240 parameters_->data.c_str(), | 210 parameters_->data.c_str(), |
| 241 parameters_->data.size()); | 211 parameters_->data.size()); |
| 242 resource->connection()->Write( | 212 resource->connection()->Write(static_cast<uint8_t>(parameters_->report_id), |
| 243 buffer, | 213 buffer, |
| 244 parameters_->data.size(), | 214 base::Bind(&HidSendFunction::OnFinished, this)); |
| 245 base::Bind(&HidSendFunction::OnFinished, this)); | |
| 246 } | 215 } |
| 247 | 216 |
| 248 void HidSendFunction::OnFinished(bool success, size_t bytes) { | 217 void HidSendFunction::OnFinished(bool success, size_t bytes) { |
| 249 if (!success) { | 218 if (!success) { |
| 250 CompleteWithError(kErrorTransfer); | 219 CompleteWithError(kErrorTransfer); |
| 251 return; | 220 return; |
| 252 } | 221 } |
| 253 AsyncWorkCompleted(); | 222 AsyncWorkCompleted(); |
| 254 } | 223 } |
| 255 | 224 |
| 256 HidReceiveFeatureReportFunction::HidReceiveFeatureReportFunction() {} | 225 HidReceiveFeatureReportFunction::HidReceiveFeatureReportFunction() {} |
| 257 | 226 |
| 258 HidReceiveFeatureReportFunction::~HidReceiveFeatureReportFunction() {} | 227 HidReceiveFeatureReportFunction::~HidReceiveFeatureReportFunction() {} |
| 259 | 228 |
| 260 bool HidReceiveFeatureReportFunction::Prepare() { | 229 bool HidReceiveFeatureReportFunction::Prepare() { |
| 261 parameters_ = hid::ReceiveFeatureReport::Params::Create(*args_); | 230 parameters_ = hid::ReceiveFeatureReport::Params::Create(*args_); |
| 262 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 231 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 263 return true; | 232 return true; |
| 264 } | 233 } |
| 265 | 234 |
| 266 void HidReceiveFeatureReportFunction::AsyncWorkStart() { | 235 void HidReceiveFeatureReportFunction::AsyncWorkStart() { |
| 267 int connection_id = parameters_->connection_id; | 236 int connection_id = parameters_->connection_id; |
| 268 HidConnectionResource* resource = | 237 HidConnectionResource* resource = |
| 269 manager_->Get(extension_->id(), connection_id); | 238 connection_manager_->Get(extension_->id(), connection_id); |
| 270 if (!resource) { | 239 if (!resource) { |
| 271 CompleteWithError(kErrorConnectionNotFound); | 240 CompleteWithError(kErrorConnectionNotFound); |
| 272 return; | 241 return; |
| 273 } | 242 } |
| 274 buffer_ = new net::IOBuffer(parameters_->size); | 243 buffer_ = new net::IOBufferWithSize(parameters_->size); |
| 275 resource->connection()->GetFeatureReport( | 244 resource->connection()->GetFeatureReport( |
| 245 static_cast<uint8_t>(parameters_->report_id), |
| 276 buffer_, | 246 buffer_, |
| 277 parameters_->size, | |
| 278 base::Bind(&HidReceiveFeatureReportFunction::OnFinished, this)); | 247 base::Bind(&HidReceiveFeatureReportFunction::OnFinished, this)); |
| 279 } | 248 } |
| 280 | 249 |
| 281 void HidReceiveFeatureReportFunction::OnFinished(bool success, size_t bytes) { | 250 void HidReceiveFeatureReportFunction::OnFinished(bool success, size_t bytes) { |
| 282 if (!success) { | 251 if (!success) { |
| 283 CompleteWithError(kErrorTransfer); | 252 CompleteWithError(kErrorTransfer); |
| 284 return; | 253 return; |
| 285 } | 254 } |
| 286 | 255 |
| 287 SetResult(base::BinaryValue::CreateWithCopiedBuffer(buffer_->data(), bytes)); | 256 SetResult(base::BinaryValue::CreateWithCopiedBuffer(buffer_->data(), bytes)); |
| 288 AsyncWorkCompleted(); | 257 AsyncWorkCompleted(); |
| 289 } | 258 } |
| 290 | 259 |
| 291 HidSendFeatureReportFunction::HidSendFeatureReportFunction() {} | 260 HidSendFeatureReportFunction::HidSendFeatureReportFunction() {} |
| 292 | 261 |
| 293 HidSendFeatureReportFunction::~HidSendFeatureReportFunction() {} | 262 HidSendFeatureReportFunction::~HidSendFeatureReportFunction() {} |
| 294 | 263 |
| 295 bool HidSendFeatureReportFunction::Prepare() { | 264 bool HidSendFeatureReportFunction::Prepare() { |
| 296 parameters_ = hid::SendFeatureReport::Params::Create(*args_); | 265 parameters_ = hid::SendFeatureReport::Params::Create(*args_); |
| 297 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 266 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 298 return true; | 267 return true; |
| 299 } | 268 } |
| 300 | 269 |
| 301 void HidSendFeatureReportFunction::AsyncWorkStart() { | 270 void HidSendFeatureReportFunction::AsyncWorkStart() { |
| 302 int connection_id = parameters_->connection_id; | 271 int connection_id = parameters_->connection_id; |
| 303 HidConnectionResource* resource = | 272 HidConnectionResource* resource = |
| 304 manager_->Get(extension_->id(), connection_id); | 273 connection_manager_->Get(extension_->id(), connection_id); |
| 305 if (!resource) { | 274 if (!resource) { |
| 306 CompleteWithError(kErrorConnectionNotFound); | 275 CompleteWithError(kErrorConnectionNotFound); |
| 307 return; | 276 return; |
| 308 } | 277 } |
| 309 scoped_refptr<net::IOBuffer> buffer( | 278 scoped_refptr<net::IOBufferWithSize> buffer( |
| 310 new net::WrappedIOBuffer(parameters_->data.c_str())); | 279 new net::IOBufferWithSize(parameters_->data.size())); |
| 311 resource->connection()->SendFeatureReport( | 280 resource->connection()->SendFeatureReport( |
| 281 static_cast<uint8_t>(parameters_->report_id), |
| 312 buffer, | 282 buffer, |
| 313 parameters_->data.size(), | |
| 314 base::Bind(&HidSendFeatureReportFunction::OnFinished, this)); | 283 base::Bind(&HidSendFeatureReportFunction::OnFinished, this)); |
| 315 } | 284 } |
| 316 | 285 |
| 317 void HidSendFeatureReportFunction::OnFinished(bool success, size_t bytes) { | 286 void HidSendFeatureReportFunction::OnFinished(bool success, size_t bytes) { |
| 318 if (!success) { | 287 if (!success) { |
| 319 CompleteWithError(kErrorTransfer); | 288 CompleteWithError(kErrorTransfer); |
| 320 return; | 289 return; |
| 321 } | 290 } |
| 322 AsyncWorkCompleted(); | 291 AsyncWorkCompleted(); |
| 323 } | 292 } |
| 324 | 293 |
| 325 } // namespace extensions | 294 } // namespace extensions |
| OLD | NEW |