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
3 // found in the LICENSE file.
5 #include "components/usb_service/usb_device_impl.h"
9 #include "base/stl_util.h"
10 #include "components/usb_service/usb_context.h"
11 #include "components/usb_service/usb_device_handle_impl.h"
12 #include "components/usb_service/usb_error.h"
13 #include "components/usb_service/usb_interface_impl.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "third_party/libusb/src/libusb/libusb.h"
17 #if defined(OS_CHROMEOS)
18 #include "base/sys_info.h"
19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "chromeos/dbus/permission_broker_client.h"
21 #endif // defined(OS_CHROMEOS)
23 using content::BrowserThread
;
27 #if defined(OS_CHROMEOS)
28 void OnRequestUsbAccessReplied(
29 const base::Callback
<void(bool success
)>& callback
,
31 BrowserThread::PostTask(
32 BrowserThread::FILE, FROM_HERE
, base::Bind(callback
, success
));
34 #endif // defined(OS_CHROMEOS)
38 namespace usb_service
{
40 UsbDeviceImpl::UsbDeviceImpl(scoped_refptr
<UsbContext
> context
,
41 PlatformUsbDevice platform_device
,
45 : UsbDevice(vendor_id
, product_id
, unique_id
),
46 platform_device_(platform_device
),
48 CHECK(platform_device
) << "platform_device cannot be NULL";
49 libusb_ref_device(platform_device
);
52 UsbDeviceImpl::~UsbDeviceImpl() {
53 DCHECK(thread_checker_
.CalledOnValidThread());
54 for (HandlesVector::iterator it
= handles_
.begin(); it
!= handles_
.end();
56 (*it
)->InternalClose();
58 STLClearObject(&handles_
);
59 libusb_unref_device(platform_device_
);
62 #if defined(OS_CHROMEOS)
64 void UsbDeviceImpl::RequestUsbAcess(
66 const base::Callback
<void(bool success
)>& callback
) {
67 DCHECK(thread_checker_
.CalledOnValidThread());
69 // ChromeOS builds on non-ChromeOS machines (dev) should not attempt to
70 // use permission broker.
71 if (base::SysInfo::IsRunningOnChromeOS()) {
72 chromeos::PermissionBrokerClient
* client
=
73 chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient();
74 DCHECK(client
) << "Could not get permission broker client.";
80 BrowserThread::PostTask(
83 base::Bind(&chromeos::PermissionBrokerClient::RequestUsbAccess
,
84 base::Unretained(client
),
88 base::Bind(&OnRequestUsbAccessReplied
, callback
)));
94 scoped_refptr
<UsbDeviceHandle
> UsbDeviceImpl::Open() {
95 DCHECK(thread_checker_
.CalledOnValidThread());
96 PlatformUsbDeviceHandle handle
;
97 const int rv
= libusb_open(platform_device_
, &handle
);
98 if (LIBUSB_SUCCESS
== rv
) {
99 scoped_refptr
<UsbConfigDescriptor
> interfaces
= ListInterfaces();
102 scoped_refptr
<UsbDeviceHandleImpl
> device_handle
=
103 new UsbDeviceHandleImpl(context_
, this, handle
, interfaces
);
104 handles_
.push_back(device_handle
);
105 return device_handle
;
107 VLOG(1) << "Failed to open device: " << ConvertErrorToString(rv
);
112 bool UsbDeviceImpl::Close(scoped_refptr
<UsbDeviceHandle
> handle
) {
113 DCHECK(thread_checker_
.CalledOnValidThread());
115 for (HandlesVector::iterator it
= handles_
.begin(); it
!= handles_
.end();
118 (*it
)->InternalClose();
126 scoped_refptr
<UsbConfigDescriptor
> UsbDeviceImpl::ListInterfaces() {
127 DCHECK(thread_checker_
.CalledOnValidThread());
129 PlatformUsbConfigDescriptor platform_config
;
131 libusb_get_active_config_descriptor(platform_device_
, &platform_config
);
132 if (rv
== LIBUSB_SUCCESS
) {
133 return new UsbConfigDescriptorImpl(platform_config
);
135 VLOG(1) << "Failed to get config descriptor: " << ConvertErrorToString(rv
);
140 void UsbDeviceImpl::OnDisconnect() {
141 DCHECK(thread_checker_
.CalledOnValidThread());
142 HandlesVector handles
;
143 swap(handles
, handles_
);
144 for (HandlesVector::iterator it
= handles
.begin(); it
!= handles
.end(); ++it
)
145 (*it
)->InternalClose();
148 } // namespace usb_service