Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / usb / usb_device.cc
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.
4
5 #include "chrome/browser/usb/usb_device.h"
6
7 #include <algorithm>
8
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"
14
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)
20
21 using content::BrowserThread;
22
23 namespace {
24
25 #if defined(OS_CHROMEOS)
26 void OnRequestUsbAccessReplied(
27     const base::Callback<void(bool success)>& callback,
28     bool success) {
29   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
30                           base::Bind(callback, success));
31 }
32 #endif  // defined(OS_CHROMEOS)
33
34 }  // namespace
35
36 UsbDevice::UsbDevice(
37     scoped_refptr<UsbContext> context,
38     PlatformUsbDevice platform_device,
39     uint16 vendor_id,
40     uint16 product_id,
41     uint32 unique_id)
42     : platform_device_(platform_device),
43       vendor_id_(vendor_id),
44       product_id_(product_id),
45       unique_id_(unique_id),
46       context_(context) {
47   CHECK(platform_device) << "platform_device cannot be NULL";
48   libusb_ref_device(platform_device);
49 }
50
51 UsbDevice::UsbDevice()
52     : platform_device_(NULL),
53       vendor_id_(0),
54       product_id_(0),
55       unique_id_(0),
56       context_(NULL) {
57 }
58
59 UsbDevice::~UsbDevice() {
60   DCHECK(thread_checker_.CalledOnValidThread());
61   for (HandlesVector::iterator it = handles_.begin();
62       it != handles_.end();
63       ++it) {
64     (*it)->InternalClose();
65   }
66   STLClearObject(&handles_);
67   libusb_unref_device(platform_device_);
68 }
69
70 #if defined(OS_CHROMEOS)
71
72 void UsbDevice::RequestUsbAcess(
73     int interface_id,
74     const base::Callback<void(bool success)>& callback) {
75   DCHECK(thread_checker_.CalledOnValidThread());
76
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.";
83     if (!client) {
84       callback.Run(false);
85       return;
86     }
87
88     BrowserThread::PostTask(
89         BrowserThread::UI, FROM_HERE,
90         base::Bind(&chromeos::PermissionBrokerClient::RequestUsbAccess,
91                    base::Unretained(client),
92                    this->vendor_id_,
93                    this->product_id_,
94                    interface_id,
95                    base::Bind(&OnRequestUsbAccessReplied, callback)));
96   }
97 }
98
99 #endif
100
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();
107     if (!interfaces)
108       return NULL;
109     scoped_refptr<UsbDeviceHandle> device_handle =
110         new UsbDeviceHandle(context_, this, handle, interfaces);
111     handles_.push_back(device_handle);
112     return device_handle;
113   }
114   return NULL;
115 }
116
117 bool UsbDevice::Close(scoped_refptr<UsbDeviceHandle> handle) {
118   DCHECK(thread_checker_.CalledOnValidThread());
119
120   for (HandlesVector::iterator it = handles_.begin();
121       it != handles_.end();
122       ++it) {
123     if (*it == handle) {
124       (*it)->InternalClose();
125       handles_.erase(it);
126       return true;
127     }
128   }
129   return false;
130 }
131
132 scoped_refptr<UsbConfigDescriptor> UsbDevice::ListInterfaces() {
133   DCHECK(thread_checker_.CalledOnValidThread());
134
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);
140
141   return NULL;
142 }
143
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 =
149       handles.begin();
150       it != handles.end();
151       ++it) {
152     (*it)->InternalClose();
153   }
154 }