Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/usb/usb_api.h" | 5 #include "chrome/browser/extensions/api/usb/usb_api.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop/message_loop_proxy.h" | |
| 11 #include "chrome/browser/extensions/api/usb/usb_device_resource.h" | 12 #include "chrome/browser/extensions/api/usb/usb_device_resource.h" |
| 12 #include "chrome/browser/extensions/extension_system.h" | 13 #include "chrome/browser/extensions/extension_system.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/usb/usb_device_handle.h" | 15 #include "chrome/browser/usb/usb_device_handle.h" |
| 15 #include "chrome/browser/usb/usb_service.h" | 16 #include "chrome/browser/usb/usb_service.h" |
| 16 #include "chrome/common/extensions/api/usb.h" | 17 #include "chrome/common/extensions/api/usb.h" |
| 17 #include "chrome/common/extensions/permissions/permissions_data.h" | 18 #include "chrome/common/extensions/permissions/permissions_data.h" |
| 18 #include "chrome/common/extensions/permissions/usb_device_permission.h" | 19 #include "chrome/common/extensions/permissions/usb_device_permission.h" |
| 19 | 20 |
| 20 namespace BulkTransfer = extensions::api::usb::BulkTransfer; | |
| 21 namespace ClaimInterface = extensions::api::usb::ClaimInterface; | |
| 22 namespace ListInterfaces = extensions::api::usb::ListInterfaces; | |
| 23 namespace CloseDevice = extensions::api::usb::CloseDevice; | |
| 24 namespace ControlTransfer = extensions::api::usb::ControlTransfer; | |
| 25 namespace FindDevices = extensions::api::usb::FindDevices; | |
| 26 namespace InterruptTransfer = extensions::api::usb::InterruptTransfer; | |
| 27 namespace IsochronousTransfer = extensions::api::usb::IsochronousTransfer; | |
| 28 namespace ReleaseInterface = extensions::api::usb::ReleaseInterface; | |
| 29 namespace ResetDevice = extensions::api::usb::ResetDevice; | |
| 30 namespace SetInterfaceAlternateSetting = | |
| 31 extensions::api::usb::SetInterfaceAlternateSetting; | |
| 32 namespace usb = extensions::api::usb; | 21 namespace usb = extensions::api::usb; |
| 22 namespace BulkTransfer = usb::BulkTransfer; | |
| 23 namespace ClaimInterface = usb::ClaimInterface; | |
| 24 namespace ListInterfaces = usb::ListInterfaces; | |
| 25 namespace CloseDevice = usb::CloseDevice; | |
| 26 namespace ControlTransfer = usb::ControlTransfer; | |
| 27 namespace FindDevices = usb::FindDevices; | |
| 28 namespace InterruptTransfer = usb::InterruptTransfer; | |
| 29 namespace IsochronousTransfer = usb::IsochronousTransfer; | |
| 30 namespace ReleaseInterface = usb::ReleaseInterface; | |
| 31 namespace ResetDevice = usb::ResetDevice; | |
| 32 namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting; | |
| 33 namespace GetDevices = usb::GetDevices; | |
| 34 namespace OpenDevice = usb::OpenDevice; | |
|
asargent_no_longer_on_chrome
2013/08/22 21:06:13
nit: can you sort these alphabetically? It would m
Bei Zhang
2013/08/23 22:52:00
Done.
| |
| 33 | 35 |
| 34 using content::BrowserThread; | 36 using content::BrowserThread; |
| 35 using std::string; | 37 using std::string; |
| 36 using std::vector; | 38 using std::vector; |
| 37 using usb::ControlTransferInfo; | 39 using usb::ControlTransferInfo; |
| 38 using usb::Device; | 40 using usb::Device; |
| 41 using usb::DeviceHandle; | |
| 39 using usb::Direction; | 42 using usb::Direction; |
| 40 using usb::EndpointDescriptor; | 43 using usb::EndpointDescriptor; |
| 41 using usb::GenericTransferInfo; | 44 using usb::GenericTransferInfo; |
| 42 using usb::InterfaceDescriptor; | 45 using usb::InterfaceDescriptor; |
| 43 using usb::IsochronousTransferInfo; | 46 using usb::IsochronousTransferInfo; |
| 44 using usb::Recipient; | 47 using usb::Recipient; |
| 45 using usb::RequestType; | 48 using usb::RequestType; |
| 46 using usb::SynchronizationType; | 49 using usb::SynchronizationType; |
| 47 using usb::TransferType; | 50 using usb::TransferType; |
| 48 using usb::UsageType; | 51 using usb::UsageType; |
| 49 | 52 |
| 53 typedef scoped_ptr<std::vector<scoped_refptr<UsbDevice> > > ScopedDeviceVector; | |
| 54 | |
| 50 namespace { | 55 namespace { |
| 51 | 56 |
| 52 static const char kDataKey[] = "data"; | 57 static const char kDataKey[] = "data"; |
| 53 static const char kResultCodeKey[] = "resultCode"; | 58 static const char kResultCodeKey[] = "resultCode"; |
| 54 | 59 |
| 55 static const char kErrorCancelled[] = "Transfer was cancelled."; | 60 static const char kErrorCancelled[] = "Transfer was cancelled."; |
| 56 static const char kErrorDisconnect[] = "Device disconnected."; | 61 static const char kErrorDisconnect[] = "Device disconnected."; |
| 57 static const char kErrorGeneric[] = "Transfer failed."; | 62 static const char kErrorGeneric[] = "Transfer failed."; |
| 58 static const char kErrorOverflow[] = "Inbound transfer overflow."; | 63 static const char kErrorOverflow[] = "Inbound transfer overflow."; |
| 59 static const char kErrorStalled[] = "Transfer stalled."; | 64 static const char kErrorStalled[] = "Transfer stalled."; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 77 static const char kErrorPermissionDenied[] = | 82 static const char kErrorPermissionDenied[] = |
| 78 "Permission to access device was denied"; | 83 "Permission to access device was denied"; |
| 79 static const char kErrorInvalidTransferLength[] = "Transfer length must be a " | 84 static const char kErrorInvalidTransferLength[] = "Transfer length must be a " |
| 80 "positive number less than 104,857,600."; | 85 "positive number less than 104,857,600."; |
| 81 static const char kErrorInvalidNumberOfPackets[] = "Number of packets must be " | 86 static const char kErrorInvalidNumberOfPackets[] = "Number of packets must be " |
| 82 "a positive number less than 4,194,304."; | 87 "a positive number less than 4,194,304."; |
| 83 static const char kErrorInvalidPacketLength[] = "Packet length must be a " | 88 static const char kErrorInvalidPacketLength[] = "Packet length must be a " |
| 84 "positive number less than 65,536."; | 89 "positive number less than 65,536."; |
| 85 static const char kErrorResetDevice[] = | 90 static const char kErrorResetDevice[] = |
| 86 "Error resetting the device. The device has been closed."; | 91 "Error resetting the device. The device has been closed."; |
| 92 static const char kErrorOpen[] = "Failed to open device."; | |
| 87 | 93 |
| 88 static const size_t kMaxTransferLength = 100 * 1024 * 1024; | 94 static const size_t kMaxTransferLength = 100 * 1024 * 1024; |
| 89 static const int kMaxPackets = 4 * 1024 * 1024; | 95 static const int kMaxPackets = 4 * 1024 * 1024; |
| 90 static const int kMaxPacketLength = 64 * 1024; | 96 static const int kMaxPacketLength = 64 * 1024; |
| 91 | 97 |
| 92 static UsbDevice* device_for_test_ = NULL; | 98 static UsbDevice* device_for_test_ = NULL; |
| 93 | 99 |
| 94 static bool ConvertDirectionToApi(const UsbEndpointDirection& input, | 100 static bool ConvertDirectionToApi(const UsbEndpointDirection& input, |
| 95 Direction* output) { | 101 Direction* output) { |
| 96 switch (input) { | 102 switch (input) { |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 297 UsbTransferStatus status, | 303 UsbTransferStatus status, |
| 298 scoped_refptr<net::IOBuffer> data, | 304 scoped_refptr<net::IOBuffer> data, |
| 299 size_t length) { | 305 size_t length) { |
| 300 base::DictionaryValue* result = new base::DictionaryValue(); | 306 base::DictionaryValue* result = new base::DictionaryValue(); |
| 301 result->SetInteger(kResultCodeKey, status); | 307 result->SetInteger(kResultCodeKey, status); |
| 302 result->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer(data->data(), | 308 result->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer(data->data(), |
| 303 length)); | 309 length)); |
| 304 return result; | 310 return result; |
| 305 } | 311 } |
| 306 | 312 |
| 307 static base::Value* PopulateDevice(int handle, int vendor_id, int product_id) { | 313 base::Value* PopulateDeviceHandle(int resource_id, |
| 308 Device device; | 314 int vendor_id, |
| 309 device.handle = handle; | 315 int product_id) { |
| 310 device.vendor_id = vendor_id; | 316 DeviceHandle result; |
| 311 device.product_id = product_id; | 317 result.handle = resource_id; |
| 312 return device.ToValue().release(); | 318 result.vendor_id.reset(new int(vendor_id)); |
| 319 result.product_id.reset(new int(product_id)); | |
| 320 return result.ToValue().release(); | |
| 313 } | 321 } |
| 314 | 322 |
| 315 static base::Value* PopulateInterfaceDescriptor(int interface_number, | 323 base::Value* PopulateDevice(UsbDevice* device) { |
| 316 int alternate_setting, int interface_class, int interface_subclass, | 324 Device result; |
| 317 int interface_protocol, | 325 result.device = device->unique_id(); |
| 318 std::vector<linked_ptr<EndpointDescriptor> >* endpoints) { | 326 result.vendor_id.reset(new int(device->vendor_id())); |
| 327 result.product_id.reset(new int(device->product_id())); | |
| 328 return result.ToValue().release(); | |
| 329 } | |
| 330 | |
| 331 base::Value* PopulateInterfaceDescriptor( | |
| 332 int interface_number, | |
| 333 int alternate_setting, | |
| 334 int interface_class, | |
| 335 int interface_subclass, | |
| 336 int interface_protocol, | |
| 337 std::vector<linked_ptr<EndpointDescriptor> >* endpoints) { | |
|
asargent_no_longer_on_chrome
2013/08/22 21:06:13
nit: It looks like you removed the "static" linkag
Bei Zhang
2013/08/23 22:52:00
Done.
| |
| 319 InterfaceDescriptor descriptor; | 338 InterfaceDescriptor descriptor; |
| 320 descriptor.interface_number = interface_number; | 339 descriptor.interface_number = interface_number; |
| 321 descriptor.alternate_setting = alternate_setting; | 340 descriptor.alternate_setting = alternate_setting; |
| 322 descriptor.interface_class = interface_class; | 341 descriptor.interface_class = interface_class; |
| 323 descriptor.interface_subclass = interface_subclass; | 342 descriptor.interface_subclass = interface_subclass; |
| 324 descriptor.interface_protocol = interface_protocol; | 343 descriptor.interface_protocol = interface_protocol; |
| 325 descriptor.endpoints = *endpoints; | 344 descriptor.endpoints = *endpoints; |
| 326 return descriptor.ToValue().release(); | 345 return descriptor.ToValue().release(); |
| 327 } | 346 } |
| 328 | 347 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 const bool converted = ConvertRecipient(input, output); | 414 const bool converted = ConvertRecipient(input, output); |
| 396 if (!converted) | 415 if (!converted) |
| 397 SetError(kErrorConvertRecipient); | 416 SetError(kErrorConvertRecipient); |
| 398 return converted; | 417 return converted; |
| 399 } | 418 } |
| 400 | 419 |
| 401 UsbFindDevicesFunction::UsbFindDevicesFunction() {} | 420 UsbFindDevicesFunction::UsbFindDevicesFunction() {} |
| 402 | 421 |
| 403 UsbFindDevicesFunction::~UsbFindDevicesFunction() {} | 422 UsbFindDevicesFunction::~UsbFindDevicesFunction() {} |
| 404 | 423 |
| 405 void UsbFindDevicesFunction::SetDeviceForTest(UsbDevice* device) { | |
| 406 device_for_test_ = device; | |
| 407 } | |
| 408 | |
| 409 bool UsbFindDevicesFunction::Prepare() { | 424 bool UsbFindDevicesFunction::Prepare() { |
| 410 parameters_ = FindDevices::Params::Create(*args_); | 425 parameters_ = FindDevices::Params::Create(*args_); |
| 411 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 426 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 412 if (!device_for_test_) | 427 if (!device_for_test_) |
| 413 set_work_thread_id(BrowserThread::FILE); | 428 set_work_thread_id(BrowserThread::FILE); |
| 414 return true; | 429 return true; |
| 415 } | 430 } |
| 416 | 431 |
| 417 void UsbFindDevicesFunction::AsyncWorkStart() { | 432 void UsbFindDevicesFunction::AsyncWorkStart() { |
| 418 result_.reset(new base::ListValue()); | 433 result_.reset(new base::ListValue()); |
| 419 | 434 |
| 420 if (device_for_test_) { | 435 if (device_for_test_) { |
| 421 UsbDeviceResource* const resource = new UsbDeviceResource( | 436 UsbDeviceResource* const resource = new UsbDeviceResource( |
| 422 extension_->id(), | 437 extension_->id(), |
| 423 device_for_test_->Open()); | 438 device_for_test_->Open()); |
| 424 | 439 |
| 425 Device device; | 440 Device device; |
| 426 result_->Append(PopulateDevice(manager_->Add(resource), 0, 0)); | 441 result_->Append(PopulateDeviceHandle(manager_->Add(resource), 0, 0)); |
| 427 SetResult(result_.release()); | 442 SetResult(result_.release()); |
| 428 AsyncWorkCompleted(); | 443 AsyncWorkCompleted(); |
| 429 return; | 444 return; |
| 430 } | 445 } |
| 431 | 446 |
| 432 const uint16_t vendor_id = parameters_->options.vendor_id; | 447 const uint16_t vendor_id = parameters_->options.vendor_id; |
| 433 const uint16_t product_id = parameters_->options.product_id; | 448 const uint16_t product_id = parameters_->options.product_id; |
| 434 int interface_id = parameters_->options.interface_id.get() ? | 449 int interface_id = parameters_->options.interface_id.get() ? |
| 435 *parameters_->options.interface_id.get() : | 450 *parameters_->options.interface_id.get() : |
| 436 UsbDevicePermissionData::ANY_INTERFACE; | 451 UsbDevicePermissionData::ANY_INTERFACE; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 463 FROM_HERE, | 478 FROM_HERE, |
| 464 base::Bind(&UsbFindDevicesFunction::OnCompleted, this)); | 479 base::Bind(&UsbFindDevicesFunction::OnCompleted, this)); |
| 465 } | 480 } |
| 466 | 481 |
| 467 void UsbFindDevicesFunction::OnCompleted() { | 482 void UsbFindDevicesFunction::OnCompleted() { |
| 468 for (size_t i = 0; i < device_handles_.size(); ++i) { | 483 for (size_t i = 0; i < device_handles_.size(); ++i) { |
| 469 UsbDeviceHandle* const device_handle = device_handles_[i].get(); | 484 UsbDeviceHandle* const device_handle = device_handles_[i].get(); |
| 470 UsbDeviceResource* const resource = | 485 UsbDeviceResource* const resource = |
| 471 new UsbDeviceResource(extension_->id(), device_handle); | 486 new UsbDeviceResource(extension_->id(), device_handle); |
| 472 | 487 |
| 473 result_->Append(PopulateDevice(manager_->Add(resource), | 488 result_->Append(PopulateDeviceHandle(manager_->Add(resource), |
| 474 parameters_->options.vendor_id, | 489 parameters_->options.vendor_id, |
| 475 parameters_->options.product_id)); | 490 parameters_->options.product_id)); |
| 476 } | 491 } |
| 477 | 492 |
| 478 SetResult(result_.release()); | 493 SetResult(result_.release()); |
| 479 AsyncWorkCompleted(); | 494 AsyncWorkCompleted(); |
| 480 } | 495 } |
| 481 | 496 |
| 497 UsbGetDevicesFunction::UsbGetDevicesFunction() { | |
| 498 } | |
| 499 | |
| 500 UsbGetDevicesFunction::~UsbGetDevicesFunction() { | |
| 501 } | |
| 502 | |
| 503 void UsbGetDevicesFunction::SetDeviceForTest(UsbDevice* device) { | |
| 504 device_for_test_ = device; | |
| 505 } | |
| 506 | |
| 507 bool UsbGetDevicesFunction::Prepare() { | |
| 508 parameters_ = GetDevices::Params::Create(*args_); | |
| 509 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | |
| 510 if (!device_for_test_) | |
| 511 set_work_thread_id(BrowserThread::FILE); | |
| 512 return true; | |
| 513 } | |
| 514 | |
| 515 void UsbGetDevicesFunction::AsyncWorkStart() { | |
| 516 result_.reset(new base::ListValue()); | |
| 517 | |
| 518 if (device_for_test_) { | |
| 519 result_->Append(PopulateDevice(device_for_test_)); | |
| 520 SetResult(result_.release()); | |
| 521 AsyncWorkCompleted(); | |
| 522 return; | |
| 523 } | |
| 524 | |
| 525 const uint16_t vendor_id = parameters_->options.vendor_id; | |
| 526 const uint16_t product_id = parameters_->options.product_id; | |
| 527 int interface_id = parameters_->options.interface_id.get() ? | |
| 528 *parameters_->options.interface_id.get() : | |
| 529 UsbDevicePermissionData::ANY_INTERFACE; | |
| 530 UsbDevicePermission::CheckParam param(vendor_id, product_id, interface_id); | |
| 531 if (!PermissionsData::CheckAPIPermissionWithParam( | |
| 532 GetExtension(), APIPermission::kUsbDevice, ¶m)) { | |
| 533 LOG(WARNING) << "Insufficient permissions to access device."; | |
| 534 CompleteWithError(kErrorPermissionDenied); | |
| 535 return; | |
| 536 } | |
| 537 | |
| 538 UsbService* service = UsbService::GetInstance(); | |
| 539 service->FindDevices( | |
| 540 vendor_id, | |
| 541 product_id, | |
| 542 interface_id, | |
| 543 base::Bind(&UsbGetDevicesFunction::EnumerationCompletedFileThread, this)); | |
| 544 } | |
| 545 | |
| 546 void UsbGetDevicesFunction::EnumerationCompletedFileThread( | |
| 547 scoped_ptr<std::vector<scoped_refptr<UsbDevice> > > devices) { | |
| 548 for (size_t i = 0; i < devices->size(); ++i) { | |
| 549 result_->Append(PopulateDevice(devices->at(i).get())); | |
| 550 } | |
| 551 | |
| 552 SetResult(result_.release()); | |
| 553 AsyncWorkCompleted(); | |
| 554 } | |
| 555 | |
| 556 UsbOpenDeviceFunction::UsbOpenDeviceFunction() {} | |
| 557 | |
| 558 UsbOpenDeviceFunction::~UsbOpenDeviceFunction() {} | |
| 559 | |
| 560 bool UsbOpenDeviceFunction::Prepare() { | |
| 561 parameters_ = OpenDevice::Params::Create(*args_); | |
| 562 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | |
| 563 return true; | |
| 564 } | |
| 565 | |
| 566 void UsbOpenDeviceFunction::AsyncWorkStart() { | |
| 567 BrowserThread::PostTask(BrowserThread::FILE, | |
| 568 FROM_HERE, | |
| 569 base::Bind(&UsbOpenDeviceFunction::OpenDeviceOnFile, | |
| 570 this)); | |
| 571 } | |
| 572 | |
| 573 void UsbOpenDeviceFunction::OpenDeviceOnFile() { | |
| 574 UsbService* service = UsbService::GetInstance(); | |
| 575 scoped_refptr<UsbDevice> device; | |
| 576 if (device_for_test_) | |
| 577 device = device_for_test_; | |
| 578 else | |
| 579 device = service->GetDeviceById(parameters_->device.device); | |
| 580 | |
| 581 if (!device) { | |
| 582 SetError(kErrorNoDevice); | |
| 583 AsyncWorkCompleted(); | |
| 584 return; | |
| 585 } | |
| 586 | |
| 587 if (!parameters_->device.vendor_id || | |
| 588 *parameters_->device.vendor_id.get() != device->vendor_id()) { | |
| 589 SetError(kErrorOpen); | |
| 590 AsyncWorkCompleted(); | |
| 591 return; | |
| 592 } | |
| 593 | |
| 594 if (!parameters_->device.product_id || | |
| 595 *parameters_->device.product_id.get() != device->product_id()) { | |
| 596 SetError(kErrorOpen); | |
| 597 AsyncWorkCompleted(); | |
| 598 return; | |
| 599 } | |
| 600 | |
| 601 handle_ = device->Open(); | |
| 602 BrowserThread::PostTask(BrowserThread::IO, | |
| 603 FROM_HERE, | |
| 604 base::Bind(&UsbOpenDeviceFunction::OnCompleted, | |
| 605 this)); | |
| 606 } | |
| 607 | |
| 608 void UsbOpenDeviceFunction::OnCompleted() { | |
| 609 if (!handle_) { | |
| 610 SetError(kErrorOpen); | |
| 611 AsyncWorkCompleted(); | |
| 612 return; | |
| 613 } | |
| 614 | |
| 615 SetResult(PopulateDeviceHandle( | |
|
asargent_no_longer_on_chrome
2013/08/22 21:06:13
If the device handle could live on the FILE thread
Bei Zhang
2013/08/23 22:52:00
This is addressed by another CL.
On 2013/08/22 21
| |
| 616 manager_->Add(new UsbDeviceResource(extension_->id(), handle_)), | |
| 617 handle_->device()->vendor_id(), | |
| 618 handle_->device()->product_id())); | |
| 619 AsyncWorkCompleted(); | |
| 620 } | |
| 621 | |
| 482 UsbListInterfacesFunction::UsbListInterfacesFunction() {} | 622 UsbListInterfacesFunction::UsbListInterfacesFunction() {} |
| 483 | 623 |
| 484 UsbListInterfacesFunction::~UsbListInterfacesFunction() {} | 624 UsbListInterfacesFunction::~UsbListInterfacesFunction() {} |
| 485 | 625 |
| 486 bool UsbListInterfacesFunction::Prepare() { | 626 bool UsbListInterfacesFunction::Prepare() { |
| 487 parameters_ = ListInterfaces::Params::Create(*args_); | 627 parameters_ = ListInterfaces::Params::Create(*args_); |
| 488 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 628 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 489 return true; | 629 return true; |
| 490 } | 630 } |
| 491 | 631 |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1023 } | 1163 } |
| 1024 | 1164 |
| 1025 void UsbResetDeviceFunction::OnError() { | 1165 void UsbResetDeviceFunction::OnError() { |
| 1026 RemoveUsbDeviceResource(parameters_->device.handle); | 1166 RemoveUsbDeviceResource(parameters_->device.handle); |
| 1027 SetError(kErrorResetDevice); | 1167 SetError(kErrorResetDevice); |
| 1028 SetResult(new base::FundamentalValue(false)); | 1168 SetResult(new base::FundamentalValue(false)); |
| 1029 AsyncWorkCompleted(); | 1169 AsyncWorkCompleted(); |
| 1030 } | 1170 } |
| 1031 | 1171 |
| 1032 } // namespace extensions | 1172 } // namespace extensions |
| OLD | NEW |