Allow chrome.systemPrivate to be used by apps.
[chromium-blink-merge.git] / components / usb_service / usb_device_impl.cc
blob98c3a49e3bdd81b4199a0b364dd5589f2f6f09a0
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"
7 #include <algorithm>
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;
25 namespace {
27 #if defined(OS_CHROMEOS)
28 void OnRequestUsbAccessReplied(
29 const base::Callback<void(bool success)>& callback,
30 bool success) {
31 BrowserThread::PostTask(
32 BrowserThread::FILE, FROM_HERE, base::Bind(callback, success));
34 #endif // defined(OS_CHROMEOS)
36 } // namespace
38 namespace usb_service {
40 UsbDeviceImpl::UsbDeviceImpl(scoped_refptr<UsbContext> context,
41 PlatformUsbDevice platform_device,
42 uint16 vendor_id,
43 uint16 product_id,
44 uint32 unique_id)
45 : UsbDevice(vendor_id, product_id, unique_id),
46 platform_device_(platform_device),
47 context_(context) {
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();
55 ++it) {
56 (*it)->InternalClose();
58 STLClearObject(&handles_);
59 libusb_unref_device(platform_device_);
62 #if defined(OS_CHROMEOS)
64 void UsbDeviceImpl::RequestUsbAcess(
65 int interface_id,
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.";
75 if (!client) {
76 callback.Run(false);
77 return;
80 BrowserThread::PostTask(
81 BrowserThread::UI,
82 FROM_HERE,
83 base::Bind(&chromeos::PermissionBrokerClient::RequestUsbAccess,
84 base::Unretained(client),
85 vendor_id(),
86 product_id(),
87 interface_id,
88 base::Bind(&OnRequestUsbAccessReplied, callback)));
92 #endif
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();
100 if (!interfaces)
101 return NULL;
102 scoped_refptr<UsbDeviceHandleImpl> device_handle =
103 new UsbDeviceHandleImpl(context_, this, handle, interfaces);
104 handles_.push_back(device_handle);
105 return device_handle;
106 } else {
107 VLOG(1) << "Failed to open device: " << ConvertErrorToString(rv);
108 return NULL;
112 bool UsbDeviceImpl::Close(scoped_refptr<UsbDeviceHandle> handle) {
113 DCHECK(thread_checker_.CalledOnValidThread());
115 for (HandlesVector::iterator it = handles_.begin(); it != handles_.end();
116 ++it) {
117 if (*it == handle) {
118 (*it)->InternalClose();
119 handles_.erase(it);
120 return true;
123 return false;
126 scoped_refptr<UsbConfigDescriptor> UsbDeviceImpl::ListInterfaces() {
127 DCHECK(thread_checker_.CalledOnValidThread());
129 PlatformUsbConfigDescriptor platform_config;
130 const int rv =
131 libusb_get_active_config_descriptor(platform_device_, &platform_config);
132 if (rv == LIBUSB_SUCCESS) {
133 return new UsbConfigDescriptorImpl(platform_config);
134 } else {
135 VLOG(1) << "Failed to get config descriptor: " << ConvertErrorToString(rv);
136 return NULL;
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