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 15using content::BrowserThread; 16 17UsbDevice::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 30UsbDevice::UsbDevice() 31 : platform_device_(NULL), 32 vendor_id_(0), 33 product_id_(0), 34 context_(NULL) { 35} 36 37UsbDevice::~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 48scoped_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 61bool 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 76bool 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 88void 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