1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/usb/usb_device.h"
9 #include "base/stl_util.h"
10 #include "chrome/browser/usb/usb_context.h"
11 #include "chrome/browser/usb/usb_device_handle.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "third_party/libusb/src/libusb/libusb.h"
15 #if defined(OS_CHROMEOS)
16 #include "base/sys_info.h"
17 #include "chromeos/dbus/dbus_thread_manager.h"
18 #include "chromeos/dbus/permission_broker_client.h"
19 #endif // defined(OS_CHROMEOS)
21 using content::BrowserThread
;
25 #if defined(OS_CHROMEOS)
26 void OnRequestUsbAccessReplied(
27 const base::Callback
<void(bool success
)>& callback
,
29 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
30 base::Bind(callback
, success
));
32 #endif // defined(OS_CHROMEOS)
37 scoped_refptr
<UsbContext
> context
,
38 PlatformUsbDevice platform_device
,
42 : platform_device_(platform_device
),
43 vendor_id_(vendor_id
),
44 product_id_(product_id
),
45 unique_id_(unique_id
),
47 CHECK(platform_device
) << "platform_device cannot be NULL";
48 libusb_ref_device(platform_device
);
51 UsbDevice::UsbDevice()
52 : platform_device_(NULL
),
59 UsbDevice::~UsbDevice() {
60 DCHECK(thread_checker_
.CalledOnValidThread());
61 for (HandlesVector::iterator it
= handles_
.begin();
64 (*it
)->InternalClose();
66 STLClearObject(&handles_
);
67 libusb_unref_device(platform_device_
);
70 #if defined(OS_CHROMEOS)
72 void UsbDevice::RequestUsbAcess(
74 const base::Callback
<void(bool success
)>& callback
) {
75 DCHECK(thread_checker_
.CalledOnValidThread());
77 // ChromeOS builds on non-ChromeOS machines (dev) should not attempt to
78 // use permission broker.
79 if (base::SysInfo::IsRunningOnChromeOS()) {
80 chromeos::PermissionBrokerClient
* client
=
81 chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient();
82 DCHECK(client
) << "Could not get permission broker client.";
88 BrowserThread::PostTask(
89 BrowserThread::UI
, FROM_HERE
,
90 base::Bind(&chromeos::PermissionBrokerClient::RequestUsbAccess
,
91 base::Unretained(client
),
95 base::Bind(&OnRequestUsbAccessReplied
, callback
)));
101 scoped_refptr
<UsbDeviceHandle
> UsbDevice::Open() {
102 DCHECK(thread_checker_
.CalledOnValidThread());
103 PlatformUsbDeviceHandle handle
;
104 int rv
= libusb_open(platform_device_
, &handle
);
105 if (LIBUSB_SUCCESS
== rv
) {
106 scoped_refptr
<UsbConfigDescriptor
> interfaces
= ListInterfaces();
109 scoped_refptr
<UsbDeviceHandle
> device_handle
=
110 new UsbDeviceHandle(context_
, this, handle
, interfaces
);
111 handles_
.push_back(device_handle
);
112 return device_handle
;
117 bool UsbDevice::Close(scoped_refptr
<UsbDeviceHandle
> handle
) {
118 DCHECK(thread_checker_
.CalledOnValidThread());
120 for (HandlesVector::iterator it
= handles_
.begin();
121 it
!= handles_
.end();
124 (*it
)->InternalClose();
132 scoped_refptr
<UsbConfigDescriptor
> UsbDevice::ListInterfaces() {
133 DCHECK(thread_checker_
.CalledOnValidThread());
135 PlatformUsbConfigDescriptor platform_config
;
136 const int list_result
=
137 libusb_get_active_config_descriptor(platform_device_
, &platform_config
);
138 if (list_result
== 0)
139 return new UsbConfigDescriptor(platform_config
);
144 void UsbDevice::OnDisconnect() {
145 DCHECK(thread_checker_
.CalledOnValidThread());
146 HandlesVector handles
;
147 swap(handles
, handles_
);
148 for (std::vector
<scoped_refptr
<UsbDeviceHandle
> >::iterator it
=
152 (*it
)->InternalClose();