16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file.
46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/browser/api/usb_private/usb_private_api.h"
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include <string>
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include <vector>
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/memory/ref_counted.h"
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/core/device_client.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/usb/usb_device_filter.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/usb/usb_device_handle.h"
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "device/usb/usb_ids.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/usb/usb_service.h"
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/common/api/usb_private.h"
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace usb = extensions::core_api::usb;
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace usb_private = extensions::core_api::usb_private;
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace GetDevices = usb_private::GetDevices;
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace GetDeviceInfo = usb_private::GetDeviceInfo;
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing content::BrowserThread;
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbDevice;
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbDeviceFilter;
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbDeviceHandle;
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbService;
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitypedef std::vector<scoped_refptr<UsbDevice> > DeviceVector;
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace {
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char kErrorInitService[] = "Failed to initialize USB service.";
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char kErrorNoDevice[] = "No such device.";
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace extensions {
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)UsbPrivateGetDevicesFunction::UsbPrivateGetDevicesFunction() {
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)UsbPrivateGetDevicesFunction::~UsbPrivateGetDevicesFunction() {
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool UsbPrivateGetDevicesFunction::Prepare() {
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  parameters_ = GetDevices::Params::Create(*args_);
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return true;
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UsbPrivateGetDevicesFunction::AsyncWorkStart() {
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UsbService* service = device::DeviceClient::Get()->GetUsbService();
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!service) {
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CompleteWithError(kErrorInitService);
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::vector<UsbDeviceFilter> filters;
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  filters.resize(parameters_->filters.size());
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (size_t i = 0; i < parameters_->filters.size(); ++i) {
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CreateDeviceFilter(*parameters_->filters[i].get(), &filters[i]);
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DeviceVector devices;
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  service->GetDevices(&devices);
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_ptr<base::ListValue> result(new base::ListValue());
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (DeviceVector::iterator it = devices.begin(); it != devices.end(); ++it) {
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<UsbDevice> device = *it;
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (filters.empty() || UsbDeviceFilter::MatchesAny(device, filters)) {
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      result->Append(new base::FundamentalValue((int)device->unique_id()));
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SetResult(result.release());
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  AsyncWorkCompleted();
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)UsbPrivateGetDeviceInfoFunction::UsbPrivateGetDeviceInfoFunction() {
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)UsbPrivateGetDeviceInfoFunction::~UsbPrivateGetDeviceInfoFunction() {
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool UsbPrivateGetDeviceInfoFunction::Prepare() {
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  parameters_ = GetDeviceInfo::Params::Create(*args_);
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return true;
916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UsbPrivateGetDeviceInfoFunction::AsyncWorkStart() {
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UsbService* service = device::DeviceClient::Get()->GetUsbService();
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!service) {
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CompleteWithError(kErrorInitService);
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_refptr<UsbDevice> device =
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      service->GetDeviceById(parameters_->device_id);
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device.get()) {
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CompleteWithError(kErrorNoDevice);
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  usb_private::DeviceInfo device_info;
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  device_info.vendor_id = device->vendor_id();
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  device_info.product_id = device->product_id();
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const char* name = device::UsbIds::GetVendorName(device_info.vendor_id);
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (name) {
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    device_info.vendor_name.reset(new std::string(name));
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  name = device::UsbIds::GetProductName(device_info.vendor_id,
1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                        device_info.product_id);
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (name) {
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    device_info.product_name.reset(new std::string(name));
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::string16 utf16;
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (device->GetManufacturer(&utf16)) {
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    device_info.manufacturer_string.reset(
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        new std::string(base::UTF16ToUTF8(utf16)));
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (device->GetProduct(&utf16)) {
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    device_info.product_string.reset(new std::string(base::UTF16ToUTF8(utf16)));
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (device->GetSerialNumber(&utf16)) {
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    device_info.serial_string.reset(new std::string(base::UTF16ToUTF8(utf16)));
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SetResult(device_info.ToValue().release());
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  AsyncWorkCompleted();
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace extensions
141