| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "device/usb/usb_service.h" | 5 #include "device/usb/usb_service.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 private: | 39 private: |
| 40 // device::UsbService implementation | 40 // device::UsbService implementation |
| 41 virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) OVERRIDE; | 41 virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) OVERRIDE; |
| 42 virtual void GetDevices( | 42 virtual void GetDevices( |
| 43 std::vector<scoped_refptr<UsbDevice> >* devices) OVERRIDE; | 43 std::vector<scoped_refptr<UsbDevice> >* devices) OVERRIDE; |
| 44 | 44 |
| 45 // base::MessageLoop::DestructionObserver implementation. | 45 // base::MessageLoop::DestructionObserver implementation. |
| 46 virtual void WillDestroyCurrentMessageLoop() OVERRIDE; | 46 virtual void WillDestroyCurrentMessageLoop() OVERRIDE; |
| 47 | 47 |
| 48 // Enumerate USB devices from OS and Update devices_ map. | 48 // Enumerate USB devices from OS and update devices_ map. |
| 49 void RefreshDevices(); | 49 void RefreshDevices(); |
| 50 | 50 |
| 51 scoped_refptr<UsbContext> context_; | 51 scoped_refptr<UsbContext> context_; |
| 52 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 52 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 53 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; | 53 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; |
| 54 | 54 |
| 55 // TODO(reillyg): Figure out a better solution. | 55 // TODO(reillyg): Figure out a better solution. |
| 56 uint32 next_unique_id_; | 56 uint32 next_unique_id_; |
| 57 | 57 |
| 58 // The map from unique IDs to UsbDevices. |
| 59 typedef std::map<uint32, scoped_refptr<UsbDeviceImpl> > DeviceMap; |
| 60 DeviceMap devices_; |
| 61 |
| 58 // The map from PlatformUsbDevices to UsbDevices. | 62 // The map from PlatformUsbDevices to UsbDevices. |
| 59 typedef std::map<PlatformUsbDevice, scoped_refptr<UsbDeviceImpl> > DeviceMap; | 63 typedef std::map<PlatformUsbDevice, scoped_refptr<UsbDeviceImpl> > |
| 60 DeviceMap devices_; | 64 PlatformDeviceMap; |
| 65 PlatformDeviceMap platform_devices_; |
| 61 | 66 |
| 62 DISALLOW_COPY_AND_ASSIGN(UsbServiceImpl); | 67 DISALLOW_COPY_AND_ASSIGN(UsbServiceImpl); |
| 63 }; | 68 }; |
| 64 | 69 |
| 65 scoped_refptr<UsbDevice> UsbServiceImpl::GetDeviceById(uint32 unique_id) { | 70 scoped_refptr<UsbDevice> UsbServiceImpl::GetDeviceById(uint32 unique_id) { |
| 66 DCHECK(CalledOnValidThread()); | 71 DCHECK(CalledOnValidThread()); |
| 67 RefreshDevices(); | 72 RefreshDevices(); |
| 68 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) { | 73 DeviceMap::iterator it = devices_.find(unique_id); |
| 69 if (it->second->unique_id() == unique_id) | 74 if (it != devices_.end()) { |
| 70 return it->second; | 75 return it->second; |
| 71 } | 76 } |
| 72 return NULL; | 77 return NULL; |
| 73 } | 78 } |
| 74 | 79 |
| 75 void UsbServiceImpl::GetDevices( | 80 void UsbServiceImpl::GetDevices( |
| 76 std::vector<scoped_refptr<UsbDevice> >* devices) { | 81 std::vector<scoped_refptr<UsbDevice> >* devices) { |
| 77 DCHECK(CalledOnValidThread()); | 82 DCHECK(CalledOnValidThread()); |
| 78 STLClearObject(devices); | 83 STLClearObject(devices); |
| 79 RefreshDevices(); | 84 RefreshDevices(); |
| 80 | 85 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 if (device_count < 0) { | 118 if (device_count < 0) { |
| 114 VLOG(1) << "Failed to get device list: " | 119 VLOG(1) << "Failed to get device list: " |
| 115 << ConvertPlatformUsbErrorToString(device_count); | 120 << ConvertPlatformUsbErrorToString(device_count); |
| 116 } | 121 } |
| 117 | 122 |
| 118 std::set<UsbDevice*> connected_devices; | 123 std::set<UsbDevice*> connected_devices; |
| 119 std::vector<PlatformUsbDevice> disconnected_devices; | 124 std::vector<PlatformUsbDevice> disconnected_devices; |
| 120 | 125 |
| 121 // Populates new devices. | 126 // Populates new devices. |
| 122 for (ssize_t i = 0; i < device_count; ++i) { | 127 for (ssize_t i = 0; i < device_count; ++i) { |
| 123 if (!ContainsKey(devices_, platform_devices[i])) { | 128 if (!ContainsKey(platform_devices_, platform_devices[i])) { |
| 124 libusb_device_descriptor descriptor; | 129 libusb_device_descriptor descriptor; |
| 125 const int rv = | 130 const int rv = |
| 126 libusb_get_device_descriptor(platform_devices[i], &descriptor); | 131 libusb_get_device_descriptor(platform_devices[i], &descriptor); |
| 127 // This test is needed. A valid vendor/produce pair is required. | 132 // This test is needed. A valid vendor/produce pair is required. |
| 128 if (rv != LIBUSB_SUCCESS) { | 133 if (rv != LIBUSB_SUCCESS) { |
| 129 VLOG(1) << "Failed to get device descriptor: " | 134 VLOG(1) << "Failed to get device descriptor: " |
| 130 << ConvertPlatformUsbErrorToString(rv); | 135 << ConvertPlatformUsbErrorToString(rv); |
| 131 continue; | 136 continue; |
| 132 } | 137 } |
| 133 UsbDeviceImpl* new_device = new UsbDeviceImpl(context_, | 138 |
| 134 ui_task_runner_, | 139 uint32 unique_id; |
| 135 platform_devices[i], | 140 do { |
| 136 descriptor.idVendor, | 141 unique_id = ++next_unique_id_; |
| 137 descriptor.idProduct, | 142 } while (devices_.find(unique_id) != devices_.end()); |
| 138 ++next_unique_id_); | 143 |
| 139 devices_[platform_devices[i]] = new_device; | 144 scoped_refptr<UsbDeviceImpl> new_device( |
| 140 connected_devices.insert(new_device); | 145 new UsbDeviceImpl(context_, |
| 146 ui_task_runner_, |
| 147 platform_devices[i], |
| 148 descriptor.idVendor, |
| 149 descriptor.idProduct, |
| 150 unique_id)); |
| 151 platform_devices_[platform_devices[i]] = new_device; |
| 152 devices_[unique_id] = new_device; |
| 153 connected_devices.insert(new_device.get()); |
| 141 } else { | 154 } else { |
| 142 connected_devices.insert(devices_[platform_devices[i]].get()); | 155 connected_devices.insert(platform_devices_[platform_devices[i]].get()); |
| 143 } | 156 } |
| 144 } | 157 } |
| 145 | 158 |
| 146 // Find disconnected devices. | 159 // Find disconnected devices. |
| 147 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) { | 160 for (PlatformDeviceMap::iterator it = platform_devices_.begin(); |
| 161 it != platform_devices_.end(); |
| 162 ++it) { |
| 148 if (!ContainsKey(connected_devices, it->second.get())) { | 163 if (!ContainsKey(connected_devices, it->second.get())) { |
| 149 disconnected_devices.push_back(it->first); | 164 disconnected_devices.push_back(it->first); |
| 165 devices_.erase(it->second->unique_id()); |
| 166 it->second->OnDisconnect(); |
| 150 } | 167 } |
| 151 } | 168 } |
| 152 | 169 |
| 153 // Remove disconnected devices from devices_. | 170 // Remove disconnected devices from platform_devices_. |
| 154 for (size_t i = 0; i < disconnected_devices.size(); ++i) { | 171 for (size_t i = 0; i < disconnected_devices.size(); ++i) { |
| 155 // UsbDevice will be destroyed after this. The corresponding | 172 // UsbDevice will be destroyed after this. The corresponding |
| 156 // PlatformUsbDevice will be unref'ed during this process. | 173 // PlatformUsbDevice will be unref'ed during this process. |
| 157 devices_.erase(disconnected_devices[i]); | 174 platform_devices_.erase(disconnected_devices[i]); |
| 158 } | 175 } |
| 159 | 176 |
| 160 libusb_free_device_list(platform_devices, true); | 177 libusb_free_device_list(platform_devices, true); |
| 161 } | 178 } |
| 162 | 179 |
| 163 // static | 180 // static |
| 164 UsbService* UsbService::GetInstance( | 181 UsbService* UsbService::GetInstance( |
| 165 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 182 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
| 166 UsbService* instance = g_usb_service_instance.Get().get(); | 183 UsbService* instance = g_usb_service_instance.Get().get(); |
| 167 if (!instance) { | 184 if (!instance) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 181 } | 198 } |
| 182 return instance; | 199 return instance; |
| 183 } | 200 } |
| 184 | 201 |
| 185 // static | 202 // static |
| 186 void UsbService::SetInstanceForTest(UsbService* instance) { | 203 void UsbService::SetInstanceForTest(UsbService* instance) { |
| 187 g_usb_service_instance.Get().reset(instance); | 204 g_usb_service_instance.Get().reset(instance); |
| 188 } | 205 } |
| 189 | 206 |
| 190 } // namespace device | 207 } // namespace device |
| OLD | NEW |