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 "components/usb_service/usb_service.h" | 5 #include "components/usb_service/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" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/single_thread_task_runner.h" |
12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
13 #include "components/usb_service/usb_context.h" | 14 #include "components/usb_service/usb_context.h" |
14 #include "components/usb_service/usb_device_impl.h" | 15 #include "components/usb_service/usb_device_impl.h" |
15 #include "components/usb_service/usb_error.h" | 16 #include "components/usb_service/usb_error.h" |
16 #include "content/public/browser/browser_thread.h" | |
17 #include "third_party/libusb/src/libusb/libusb.h" | 17 #include "third_party/libusb/src/libusb/libusb.h" |
18 | 18 |
19 namespace usb_service { | 19 namespace usb_service { |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 base::LazyInstance<scoped_ptr<UsbService> >::Leaky g_usb_service_instance = | 23 base::LazyInstance<scoped_ptr<UsbService> >::Leaky g_usb_service_instance = |
24 LAZY_INSTANCE_INITIALIZER; | 24 LAZY_INSTANCE_INITIALIZER; |
25 | 25 |
26 } // namespace | 26 } // namespace |
27 | 27 |
28 typedef struct libusb_device* PlatformUsbDevice; | 28 typedef struct libusb_device* PlatformUsbDevice; |
29 typedef struct libusb_context* PlatformUsbContext; | 29 typedef struct libusb_context* PlatformUsbContext; |
30 | 30 |
31 class UsbServiceImpl | 31 class UsbServiceImpl |
32 : public UsbService, | 32 : public UsbService, |
33 private base::MessageLoop::DestructionObserver { | 33 private base::MessageLoop::DestructionObserver { |
34 public: | 34 public: |
35 explicit UsbServiceImpl(PlatformUsbContext context); | 35 explicit UsbServiceImpl( |
| 36 PlatformUsbContext context, |
| 37 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); |
36 virtual ~UsbServiceImpl(); | 38 virtual ~UsbServiceImpl(); |
37 | 39 |
38 private: | 40 private: |
39 // usb_service::UsbService implementation | 41 // usb_service::UsbService implementation |
40 virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) OVERRIDE; | 42 virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) OVERRIDE; |
41 virtual void GetDevices( | 43 virtual void GetDevices( |
42 std::vector<scoped_refptr<UsbDevice> >* devices) OVERRIDE; | 44 std::vector<scoped_refptr<UsbDevice> >* devices) OVERRIDE; |
43 | 45 |
44 // base::MessageLoop::DestructionObserver implementation. | 46 // base::MessageLoop::DestructionObserver implementation. |
45 virtual void WillDestroyCurrentMessageLoop() OVERRIDE; | 47 virtual void WillDestroyCurrentMessageLoop() OVERRIDE; |
46 | 48 |
47 // Enumerate USB devices from OS and Update devices_ map. | 49 // Enumerate USB devices from OS and Update devices_ map. |
48 void RefreshDevices(); | 50 void RefreshDevices(); |
49 | 51 |
50 scoped_refptr<UsbContext> context_; | 52 scoped_refptr<UsbContext> context_; |
| 53 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 54 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; |
51 | 55 |
52 // TODO(ikarienator): Figure out a better solution. | 56 // TODO(ikarienator): Figure out a better solution. |
53 uint32 next_unique_id_; | 57 uint32 next_unique_id_; |
54 | 58 |
55 // The map from PlatformUsbDevices to UsbDevices. | 59 // The map from PlatformUsbDevices to UsbDevices. |
56 typedef std::map<PlatformUsbDevice, scoped_refptr<UsbDeviceImpl> > DeviceMap; | 60 typedef std::map<PlatformUsbDevice, scoped_refptr<UsbDeviceImpl> > DeviceMap; |
57 DeviceMap devices_; | 61 DeviceMap devices_; |
58 | 62 |
59 DISALLOW_COPY_AND_ASSIGN(UsbServiceImpl); | 63 DISALLOW_COPY_AND_ASSIGN(UsbServiceImpl); |
60 }; | 64 }; |
(...skipping 17 matching lines...) Expand all Loading... |
78 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) { | 82 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) { |
79 devices->push_back(it->second); | 83 devices->push_back(it->second); |
80 } | 84 } |
81 } | 85 } |
82 | 86 |
83 void UsbServiceImpl::WillDestroyCurrentMessageLoop() { | 87 void UsbServiceImpl::WillDestroyCurrentMessageLoop() { |
84 DCHECK(CalledOnValidThread()); | 88 DCHECK(CalledOnValidThread()); |
85 g_usb_service_instance.Get().reset(NULL); | 89 g_usb_service_instance.Get().reset(NULL); |
86 } | 90 } |
87 | 91 |
88 UsbServiceImpl::UsbServiceImpl(PlatformUsbContext context) | 92 UsbServiceImpl::UsbServiceImpl( |
89 : context_(new UsbContext(context)), next_unique_id_(0) { | 93 PlatformUsbContext context, |
| 94 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) |
| 95 : context_(new UsbContext(context)), |
| 96 ui_task_runner_(ui_task_runner), |
| 97 next_unique_id_(0) { |
90 base::MessageLoop::current()->AddDestructionObserver(this); | 98 base::MessageLoop::current()->AddDestructionObserver(this); |
91 } | 99 } |
92 | 100 |
93 UsbServiceImpl::~UsbServiceImpl() { | 101 UsbServiceImpl::~UsbServiceImpl() { |
94 base::MessageLoop::current()->RemoveDestructionObserver(this); | 102 base::MessageLoop::current()->RemoveDestructionObserver(this); |
95 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) { | 103 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) { |
96 it->second->OnDisconnect(); | 104 it->second->OnDisconnect(); |
97 } | 105 } |
98 } | 106 } |
99 | 107 |
(...skipping 17 matching lines...) Expand all Loading... |
117 libusb_device_descriptor descriptor; | 125 libusb_device_descriptor descriptor; |
118 const int rv = | 126 const int rv = |
119 libusb_get_device_descriptor(platform_devices[i], &descriptor); | 127 libusb_get_device_descriptor(platform_devices[i], &descriptor); |
120 // This test is needed. A valid vendor/produce pair is required. | 128 // This test is needed. A valid vendor/produce pair is required. |
121 if (rv != LIBUSB_SUCCESS) { | 129 if (rv != LIBUSB_SUCCESS) { |
122 VLOG(1) << "Failed to get device descriptor: " | 130 VLOG(1) << "Failed to get device descriptor: " |
123 << ConvertErrorToString(rv); | 131 << ConvertErrorToString(rv); |
124 continue; | 132 continue; |
125 } | 133 } |
126 UsbDeviceImpl* new_device = new UsbDeviceImpl(context_, | 134 UsbDeviceImpl* new_device = new UsbDeviceImpl(context_, |
| 135 ui_task_runner_, |
127 platform_devices[i], | 136 platform_devices[i], |
128 descriptor.idVendor, | 137 descriptor.idVendor, |
129 descriptor.idProduct, | 138 descriptor.idProduct, |
130 ++next_unique_id_); | 139 ++next_unique_id_); |
131 devices_[platform_devices[i]] = new_device; | 140 devices_[platform_devices[i]] = new_device; |
132 connected_devices.insert(new_device); | 141 connected_devices.insert(new_device); |
133 } else { | 142 } else { |
134 connected_devices.insert(devices_[platform_devices[i]].get()); | 143 connected_devices.insert(devices_[platform_devices[i]].get()); |
135 } | 144 } |
136 } | 145 } |
137 | 146 |
138 // Find disconnected devices. | 147 // Find disconnected devices. |
139 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) { | 148 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) { |
140 if (!ContainsKey(connected_devices, it->second)) { | 149 if (!ContainsKey(connected_devices, it->second)) { |
141 disconnected_devices.push_back(it->first); | 150 disconnected_devices.push_back(it->first); |
142 } | 151 } |
143 } | 152 } |
144 | 153 |
145 // Remove disconnected devices from devices_. | 154 // Remove disconnected devices from devices_. |
146 for (size_t i = 0; i < disconnected_devices.size(); ++i) { | 155 for (size_t i = 0; i < disconnected_devices.size(); ++i) { |
147 // UsbDevice will be destroyed after this. The corresponding | 156 // UsbDevice will be destroyed after this. The corresponding |
148 // PlatformUsbDevice will be unref'ed during this process. | 157 // PlatformUsbDevice will be unref'ed during this process. |
149 devices_.erase(disconnected_devices[i]); | 158 devices_.erase(disconnected_devices[i]); |
150 } | 159 } |
151 | 160 |
152 libusb_free_device_list(platform_devices, true); | 161 libusb_free_device_list(platform_devices, true); |
153 } | 162 } |
154 | 163 |
155 // static | 164 // static |
156 UsbService* UsbService::GetInstance() { | 165 UsbService* UsbService::GetInstance( |
| 166 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
157 UsbService* instance = g_usb_service_instance.Get().get(); | 167 UsbService* instance = g_usb_service_instance.Get().get(); |
158 if (!instance) { | 168 if (!instance) { |
159 PlatformUsbContext context = NULL; | 169 PlatformUsbContext context = NULL; |
160 | 170 |
161 const int rv = libusb_init(&context); | 171 const int rv = libusb_init(&context); |
162 if (rv != LIBUSB_SUCCESS) { | 172 if (rv != LIBUSB_SUCCESS) { |
163 VLOG(1) << "Failed to initialize libusb: " << ConvertErrorToString(rv); | 173 VLOG(1) << "Failed to initialize libusb: " << ConvertErrorToString(rv); |
164 return NULL; | 174 return NULL; |
165 } | 175 } |
166 if (!context) | 176 if (!context) |
167 return NULL; | 177 return NULL; |
168 | 178 |
169 instance = new UsbServiceImpl(context); | 179 instance = new UsbServiceImpl(context, ui_task_runner); |
170 g_usb_service_instance.Get().reset(instance); | 180 g_usb_service_instance.Get().reset(instance); |
171 } | 181 } |
172 return instance; | 182 return instance; |
173 } | 183 } |
174 | 184 |
175 // static | 185 // static |
176 void UsbService::SetInstanceForTest(UsbService* instance) { | 186 void UsbService::SetInstanceForTest(UsbService* instance) { |
177 g_usb_service_instance.Get().reset(instance); | 187 g_usb_service_instance.Get().reset(instance); |
178 } | 188 } |
179 | 189 |
180 } // namespace usb_service | 190 } // namespace usb_service |
OLD | NEW |