Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: chrome/browser/usb/usb_service.cc

Issue 22914023: Introducing chrome.usb.getDevices/openDevice API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@usb-interface
Patch Set: Rebase to origin/master Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/usb/usb_service.h ('k') | chrome/common/extensions/api/usb.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/usb/usb_service.h" 5 #include "chrome/browser/usb/usb_service.h"
6 6
7 #include <set> 7 #include <set>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/basictypes.h"
10 #include "base/bind.h" 11 #include "base/bind.h"
11 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
13 #include "base/stl_util.h" 15 #include "base/stl_util.h"
14 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/usb/usb_context.h" 17 #include "chrome/browser/usb/usb_context.h"
18 #include "chrome/browser/usb/usb_device.h"
16 #include "chrome/browser/usb/usb_device_handle.h" 19 #include "chrome/browser/usb/usb_device_handle.h"
17 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/notification_observer.h" 21 #include "content/public/browser/notification_observer.h"
19 #include "content/public/browser/notification_registrar.h" 22 #include "content/public/browser/notification_registrar.h"
20 #include "content/public/browser/notification_service.h" 23 #include "content/public/browser/notification_service.h"
21 #include "third_party/libusb/src/libusb/libusb.h" 24 #include "third_party/libusb/src/libusb/libusb.h"
22 25
23 #if defined(OS_CHROMEOS)
24 #include "base/chromeos/chromeos_version.h"
25 #include "chromeos/dbus/dbus_thread_manager.h"
26 #include "chromeos/dbus/permission_broker_client.h"
27 #endif // defined(OS_CHROMEOS)
28
29 namespace content { 26 namespace content {
30 27
31 class NotificationDetails; 28 class NotificationDetails;
32 class NotificationSource; 29 class NotificationSource;
33 30
34 } // namespace content 31 } // namespace content
35 32
36 using content::BrowserThread; 33 using content::BrowserThread;
37 using std::vector; 34 using std::vector;
38 35
(...skipping 18 matching lines...) Expand all
57 } 54 }
58 UsbService* service_; 55 UsbService* service_;
59 content::NotificationRegistrar registrar_; 56 content::NotificationRegistrar registrar_;
60 }; 57 };
61 58
62 } // namespace 59 } // namespace
63 60
64 using content::BrowserThread; 61 using content::BrowserThread;
65 62
66 UsbService::UsbService() 63 UsbService::UsbService()
67 : context_(new UsbContext()) { 64 : context_(new UsbContext()),
65 next_unique_id_(0) {
68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
69 } 67 }
70 68
71 UsbService::~UsbService() { 69 UsbService::~UsbService() {
72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 70 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
73 for (DeviceMap::iterator it = devices_.begin(); 71 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
74 it != devices_.end(); ++it) {
75 it->second->OnDisconnect(); 72 it->second->OnDisconnect();
76 } 73 }
77 } 74 }
78 75
79 UsbService* UsbService::GetInstance() { 76 UsbService* UsbService::GetInstance() {
80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
81 // UsbService deletes itself upon APP_TERMINATING. 78 // UsbService deletes itself upon APP_TERMINATING.
82 return Singleton<UsbService, LeakySingletonTraits<UsbService> >::get(); 79 return Singleton<UsbService, LeakySingletonTraits<UsbService> >::get();
83 } 80 }
84 81
85 void UsbService::FindDevices(
86 const uint16 vendor_id,
87 const uint16 product_id,
88 int interface_id,
89 const base::Callback<void(ScopedDeviceVector vector)>& callback) {
90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
91 #if defined(OS_CHROMEOS)
92 // ChromeOS builds on non-ChromeOS machines (dev) should not attempt to
93 // use permission broker.
94 if (base::chromeos::IsRunningOnChromeOS()) {
95 chromeos::PermissionBrokerClient* client =
96 chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient();
97 DCHECK(client) << "Could not get permission broker client.";
98 if (!client) {
99 callback.Run(ScopedDeviceVector());
100 return;
101 }
102
103 BrowserThread::PostTask(
104 BrowserThread::UI,
105 FROM_HERE,
106 base::Bind(&chromeos::PermissionBrokerClient::RequestUsbAccess,
107 base::Unretained(client),
108 vendor_id,
109 product_id,
110 interface_id,
111 base::Bind(&UsbService::OnRequestUsbAccessReplied,
112 base::Unretained(this),
113 vendor_id,
114 product_id,
115 callback)));
116 } else {
117 FindDevicesImpl(vendor_id, product_id, callback, true);
118 }
119 #else
120 FindDevicesImpl(vendor_id, product_id, callback, true);
121 #endif // defined(OS_CHROMEOS)
122 }
123
124 void UsbService::GetDevices(std::vector<scoped_refptr<UsbDevice> >* devices) { 82 void UsbService::GetDevices(std::vector<scoped_refptr<UsbDevice> >* devices) {
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
126 STLClearObject(devices); 84 STLClearObject(devices);
127 RefreshDevices(); 85 RefreshDevices();
128 86
129 for (DeviceMap::iterator it = devices_.begin(); 87 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
130 it != devices_.end(); ++it) {
131 devices->push_back(it->second); 88 devices->push_back(it->second);
132 } 89 }
133 } 90 }
134 91
135 void UsbService::OnRequestUsbAccessReplied( 92 scoped_refptr<UsbDevice> UsbService::GetDeviceById(uint32 unique_id) {
136 const uint16 vendor_id,
137 const uint16 product_id,
138 const base::Callback<void(ScopedDeviceVector vectors)>& callback,
139 bool success) {
140 BrowserThread::PostTask(
141 BrowserThread::FILE,
142 FROM_HERE,
143 base::Bind(&UsbService::FindDevicesImpl,
144 base::Unretained(this),
145 vendor_id,
146 product_id,
147 callback,
148 success));
149 }
150
151 void UsbService::FindDevicesImpl(
152 const uint16 vendor_id,
153 const uint16 product_id,
154 const base::Callback<void(ScopedDeviceVector vectors)>& callback,
155 bool success) {
156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
157 ScopedDeviceVector devices(new vector<scoped_refptr<UsbDevice> >());
158
159 // If the permission broker was unable to obtain permission for the specified
160 // devices then there is no point in attempting to enumerate the devices. On
161 // platforms without a permission broker, we assume permission is granted.
162 if (!success) {
163 callback.Run(devices.Pass());
164 return;
165 }
166
167 RefreshDevices(); 94 RefreshDevices();
168 95
169 for (DeviceMap::iterator it = devices_.begin(); 96 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
170 it != devices_.end(); ++it) { 97 if (it->second->unique_id() == unique_id) return it->second;
171 if (DeviceMatches(it->second, vendor_id, product_id))
172 devices->push_back(it->second);
173 } 98 }
174 99 return NULL;
175 callback.Run(devices.Pass());
176 } 100 }
177 101
178 void UsbService::RefreshDevices() { 102 void UsbService::RefreshDevices() {
179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
180 104
181 libusb_device** platform_devices = NULL; 105 libusb_device** platform_devices = NULL;
182 const ssize_t device_count = 106 const ssize_t device_count =
183 libusb_get_device_list(context_->context(), &platform_devices); 107 libusb_get_device_list(context_->context(), &platform_devices);
184 108
185 std::set<UsbDevice*> connected_devices; 109 std::set<UsbDevice*> connected_devices;
186 vector<PlatformUsbDevice> disconnected_devices; 110 vector<PlatformUsbDevice> disconnected_devices;
187 111
188 // Populates new devices. 112 // Populates new devices.
189 for (ssize_t i = 0; i < device_count; ++i) { 113 for (ssize_t i = 0; i < device_count; ++i) {
190 if (!ContainsKey(devices_, platform_devices[i])) { 114 if (!ContainsKey(devices_, platform_devices[i])) {
191 libusb_device_descriptor descriptor; 115 libusb_device_descriptor descriptor;
192 // This test is needed. A valid vendor/produce pair is required. 116 // This test is needed. A valid vendor/produce pair is required.
193 if (0 != libusb_get_device_descriptor(platform_devices[i], &descriptor)) 117 if (0 != libusb_get_device_descriptor(platform_devices[i], &descriptor))
194 continue; 118 continue;
195 UsbDevice* new_device = new UsbDevice(context_, 119 UsbDevice* new_device = new UsbDevice(context_,
196 platform_devices[i], 120 platform_devices[i],
197 descriptor.idVendor, 121 descriptor.idVendor,
198 descriptor.idProduct); 122 descriptor.idProduct,
123 ++next_unique_id_);
199 devices_[platform_devices[i]] = new_device; 124 devices_[platform_devices[i]] = new_device;
200 connected_devices.insert(new_device); 125 connected_devices.insert(new_device);
201 } else { 126 } else {
202 connected_devices.insert(devices_[platform_devices[i]].get()); 127 connected_devices.insert(devices_[platform_devices[i]].get());
203 } 128 }
204 } 129 }
205 130
206 // Find disconnected devices. 131 // Find disconnected devices.
207 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) { 132 for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
208 if (!ContainsKey(connected_devices, it->second)) { 133 if (!ContainsKey(connected_devices, it->second)) {
209 disconnected_devices.push_back(it->first); 134 disconnected_devices.push_back(it->first);
210 } 135 }
211 } 136 }
212 137
213 // Remove disconnected devices from devices_. 138 // Remove disconnected devices from devices_.
214 for (size_t i = 0; i < disconnected_devices.size(); ++i) { 139 for (size_t i = 0; i < disconnected_devices.size(); ++i) {
215 // UsbDevice will be destroyed after this. The corresponding 140 // UsbDevice will be destroyed after this. The corresponding
216 // PlatformUsbDevice will be unref'ed during this process. 141 // PlatformUsbDevice will be unref'ed during this process.
217 devices_.erase(disconnected_devices[i]); 142 devices_.erase(disconnected_devices[i]);
218 } 143 }
219 144
220 libusb_free_device_list(platform_devices, true); 145 libusb_free_device_list(platform_devices, true);
221 } 146 }
222
223 bool UsbService::DeviceMatches(scoped_refptr<UsbDevice> device,
224 const uint16 vendor_id,
225 const uint16 product_id) {
226 return device->vendor_id() == vendor_id && device->product_id() == product_id;
227 }
OLDNEW
« no previous file with comments | « chrome/browser/usb/usb_service.h ('k') | chrome/common/extensions/api/usb.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698