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 |