diff options
author | ikarienator@chromium.org <ikarienator@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-08 19:38:11 +0000 |
---|---|---|
committer | ikarienator@chromium.org <ikarienator@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-08 19:38:11 +0000 |
commit | d165a644ac409d6e67acb1ed35d28880a5447a46 (patch) | |
tree | fd6f6e235ae35f0a6f9ddeec2f485939c7211933 /chrome/browser/usb/usb_service.cc | |
parent | 7eccd73446844b8b59776f90bcf2a8f7498215b0 (diff) | |
download | chromium_src-d165a644ac409d6e67acb1ed35d28880a5447a46.zip chromium_src-d165a644ac409d6e67acb1ed35d28880a5447a46.tar.gz chromium_src-d165a644ac409d6e67acb1ed35d28880a5447a46.tar.bz2 |
Introduce UsbDevice
Completes the separation of UsbDeviceHandle and UsbDevice.
BUG=223817
BUG=269048
Review URL: https://chromiumcodereview.appspot.com/21609002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216423 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/usb/usb_service.cc')
-rw-r--r-- | chrome/browser/usb/usb_service.cc | 151 |
1 files changed, 64 insertions, 87 deletions
diff --git a/chrome/browser/usb/usb_service.cc b/chrome/browser/usb/usb_service.cc index d850488..4425d9b 100644 --- a/chrome/browser/usb/usb_service.cc +++ b/chrome/browser/usb/usb_service.cc @@ -4,6 +4,7 @@ #include "chrome/browser/usb/usb_service.h" +#include <set> #include <vector> #include "base/bind.h" @@ -60,15 +61,19 @@ class ExitObserver : public content::NotificationObserver { } // namespace -UsbService::UsbService() : context_(new UsbContext()) { +using content::BrowserThread; + +UsbService::UsbService() + : context_(new UsbContext()) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); } UsbService::~UsbService() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - // UsbDeviceHandle::Close removes itself from devices_. - while (devices_.size()) - devices_.begin()->second->Close(); + for (DeviceMap::iterator it = devices_.begin(); + it != devices_.end(); ++it) { + it->second->OnDisconnect(); + } } UsbService* UsbService::GetInstance() { @@ -116,19 +121,14 @@ void UsbService::FindDevices( #endif // defined(OS_CHROMEOS) } -void UsbService::EnumerateDevices( - vector<scoped_refptr<UsbDeviceHandle> >* devices) { - devices->clear(); - - DeviceVector enumerated_devices; - EnumerateDevicesImpl(&enumerated_devices); +void UsbService::GetDevices(std::vector<scoped_refptr<UsbDevice> >* devices) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + STLClearObject(devices); + RefreshDevices(); - for (DeviceVector::iterator it = enumerated_devices.begin(); - it != enumerated_devices.end(); ++it) { - PlatformUsbDevice device = it->device(); - UsbDeviceHandle* const wrapper = LookupOrCreateDevice(device); - if (wrapper) - devices->push_back(wrapper); + for (DeviceMap::iterator it = devices_.begin(); + it != devices_.end(); ++it) { + devices->push_back(it->second); } } @@ -153,7 +153,8 @@ void UsbService::FindDevicesImpl( const uint16 product_id, const base::Callback<void(ScopedDeviceVector vectors)>& callback, bool success) { - ScopedDeviceVector devices(new vector<scoped_refptr<UsbDeviceHandle> >()); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + ScopedDeviceVector devices(new vector<scoped_refptr<UsbDevice> >()); // If the permission broker was unable to obtain permission for the specified // devices then there is no point in attempting to enumerate the devices. On @@ -163,88 +164,64 @@ void UsbService::FindDevicesImpl( return; } - DeviceVector enumerated_devices; - EnumerateDevicesImpl(&enumerated_devices); - - for (DeviceVector::iterator it = enumerated_devices.begin(); - it != enumerated_devices.end(); ++it) { - PlatformUsbDevice device = it->device(); - if (DeviceMatches(device, vendor_id, product_id)) { - UsbDeviceHandle* const wrapper = LookupOrCreateDevice(device); - if (wrapper) - devices->push_back(make_scoped_refptr(wrapper)); - } - } - callback.Run(devices.Pass()); -} + RefreshDevices(); -void UsbService::CloseDevice(scoped_refptr<UsbDeviceHandle> device) { - PlatformUsbDevice platform_device = libusb_get_device(device->handle()); - if (!ContainsKey(devices_, platform_device)) { - LOG(WARNING) << "CloseDevice called for device we're not tracking!"; - return; + for (DeviceMap::iterator it = devices_.begin(); + it != devices_.end(); ++it) { + if (DeviceMatches(it->second, vendor_id, product_id)) + devices->push_back(it->second); } - devices_.erase(platform_device); - libusb_close(device->handle()); -} - -UsbService::RefCountedPlatformUsbDevice::RefCountedPlatformUsbDevice( - PlatformUsbDevice device) : device_(device) { - libusb_ref_device(device_); -} - -UsbService::RefCountedPlatformUsbDevice::RefCountedPlatformUsbDevice( - const RefCountedPlatformUsbDevice& other) : device_(other.device_) { - libusb_ref_device(device_); -} - -UsbService::RefCountedPlatformUsbDevice::~RefCountedPlatformUsbDevice() { - libusb_unref_device(device_); + callback.Run(devices.Pass()); } -PlatformUsbDevice UsbService::RefCountedPlatformUsbDevice::device() { - return device_; -} +void UsbService::RefreshDevices() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); -void UsbService::EnumerateDevicesImpl(DeviceVector* output) { - STLClearObject(output); + libusb_device** platform_devices = NULL; + const ssize_t device_count = + libusb_get_device_list(context_->context(), &platform_devices); + + std::set<UsbDevice*> connected_devices; + vector<PlatformUsbDevice> disconnected_devices; + + // Populates new devices. + for (ssize_t i = 0; i < device_count; ++i) { + if (!ContainsKey(devices_, platform_devices[i])) { + libusb_device_descriptor descriptor; + // This test is needed. A valid vendor/produce pair is required. + if (0 != libusb_get_device_descriptor(platform_devices[i], &descriptor)) + continue; + UsbDevice* new_device = new UsbDevice(context_, + platform_devices[i], + descriptor.idVendor, + descriptor.idProduct); + devices_[platform_devices[i]] = new_device; + connected_devices.insert(new_device); + } else { + connected_devices.insert(devices_[platform_devices[i]].get()); + } + } - libusb_device** devices = NULL; - const ssize_t device_count = libusb_get_device_list( - context_->context(), - &devices); - if (device_count < 0) - return; + // Find disconnected devices. + for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) { + if (!ContainsKey(connected_devices, it->second)) { + disconnected_devices.push_back(it->first); + } + } - for (int i = 0; i < device_count; ++i) { - libusb_device* device = devices[i]; - libusb_ref_device(device); - output->push_back(RefCountedPlatformUsbDevice(device)); + // Remove disconnected devices from devices_. + for (size_t i = 0; i < disconnected_devices.size(); ++i) { + // UsbDevice will be destroyed after this. The corresponding + // PlatformUsbDevice will be unref'ed during this process. + devices_.erase(disconnected_devices[i]); } - libusb_free_device_list(devices, true); + libusb_free_device_list(platform_devices, true); } -bool UsbService::DeviceMatches(PlatformUsbDevice device, +bool UsbService::DeviceMatches(scoped_refptr<UsbDevice> device, const uint16 vendor_id, const uint16 product_id) { - libusb_device_descriptor descriptor; - if (libusb_get_device_descriptor(device, &descriptor)) - return false; - return descriptor.idVendor == vendor_id && descriptor.idProduct == product_id; -} - -UsbDeviceHandle* UsbService::LookupOrCreateDevice(PlatformUsbDevice device) { - if (!ContainsKey(devices_, device)) { - libusb_device_handle* handle = NULL; - if (libusb_open(device, &handle)) { - LOG(WARNING) << "Could not open device."; - return NULL; - } - - UsbDeviceHandle* wrapper = new UsbDeviceHandle(this, handle); - devices_[device] = wrapper; - } - return devices_[device].get(); + return device->vendor_id() == vendor_id && device->product_id() == product_id; } |