Home | History | Annotate | Download | only in usb
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/usb/usb_device.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/stl_util.h"
     10 #include "chrome/browser/usb/usb_context.h"
     11 #include "chrome/browser/usb/usb_device_handle.h"
     12 #include "content/public/browser/browser_thread.h"
     13 #include "third_party/libusb/src/libusb/libusb.h"
     14 
     15 using content::BrowserThread;
     16 
     17 UsbDevice::UsbDevice(
     18     scoped_refptr<UsbContext> context,
     19     PlatformUsbDevice platform_device,
     20     uint16 vendor_id,
     21     uint16 product_id)
     22     : platform_device_(platform_device),
     23       vendor_id_(vendor_id),
     24       product_id_(product_id),
     25       context_(context) {
     26   CHECK(platform_device) << "platform_device cannot be NULL";
     27   libusb_ref_device(platform_device);
     28 }
     29 
     30 UsbDevice::UsbDevice()
     31     : platform_device_(NULL),
     32       vendor_id_(0),
     33       product_id_(0),
     34       context_(NULL) {
     35 }
     36 
     37 UsbDevice::~UsbDevice() {
     38   DCHECK(thread_checker_.CalledOnValidThread());
     39   for (HandlesVector::iterator it = handles_.begin();
     40       it != handles_.end();
     41       ++it) {
     42     (*it)->InternalClose();
     43   }
     44   STLClearObject(&handles_);
     45   libusb_unref_device(platform_device_);
     46 }
     47 
     48 scoped_refptr<UsbDeviceHandle> UsbDevice::Open() {
     49   DCHECK(thread_checker_.CalledOnValidThread());
     50   PlatformUsbDeviceHandle handle;
     51   int rv = libusb_open(platform_device_, &handle);
     52   if (LIBUSB_SUCCESS == rv) {
     53     scoped_refptr<UsbDeviceHandle> device_handle =
     54         new UsbDeviceHandle(context_, this, handle);
     55     handles_.push_back(device_handle);
     56     return device_handle;
     57   }
     58   return NULL;
     59 }
     60 
     61 bool UsbDevice::Close(scoped_refptr<UsbDeviceHandle> handle) {
     62   DCHECK(thread_checker_.CalledOnValidThread());
     63 
     64   for (HandlesVector::iterator it = handles_.begin();
     65       it != handles_.end();
     66       ++it) {
     67     if (*it == handle) {
     68       (*it)->InternalClose();
     69       handles_.erase(it);
     70       return true;
     71     }
     72   }
     73   return false;
     74 }
     75 
     76 bool UsbDevice::ListInterfaces(UsbConfigDescriptor* config) {
     77   DCHECK(thread_checker_.CalledOnValidThread());
     78 
     79   PlatformUsbConfigDescriptor platform_config;
     80   const int list_result =
     81       libusb_get_active_config_descriptor(platform_device_, &platform_config);
     82   if (list_result == 0)
     83     config->Reset(platform_config);
     84 
     85   return list_result == 0;
     86 }
     87 
     88 void UsbDevice::OnDisconnect() {
     89   DCHECK(thread_checker_.CalledOnValidThread());
     90   HandlesVector handles;
     91   swap(handles, handles_);
     92   for (std::vector<scoped_refptr<UsbDeviceHandle> >::iterator it =
     93       handles.begin();
     94       it != handles.end();
     95       ++it) {
     96     (*it)->InternalClose();
     97   }
     98 }
     99