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

Side by Side Diff: device/usb/usb_device_impl.cc

Issue 1877503003: Replace libusb in the Linux/Chrome OS USB I/O path. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 "device/usb/usb_device_impl.h" 5 #include "device/usb/usb_device_impl.h"
6 6
7 #include <fcntl.h>
7 #include <stddef.h> 8 #include <stddef.h>
8 9
9 #include <algorithm> 10 #include <algorithm>
10 11
11 #include "base/bind.h" 12 #include "base/bind.h"
12 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/posix/eintr_wrapper.h"
13 #include "base/sequenced_task_runner.h" 15 #include "base/sequenced_task_runner.h"
14 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
15 #include "base/stl_util.h" 17 #include "base/stl_util.h"
16 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
17 #include "build/build_config.h" 19 #include "build/build_config.h"
18 #include "components/device_event_log/device_event_log.h" 20 #include "components/device_event_log/device_event_log.h"
19 #include "device/usb/usb_context.h" 21 #include "device/usb/usb_context.h"
20 #include "device/usb/usb_descriptors.h" 22 #include "device/usb/usb_descriptors.h"
21 #include "device/usb/usb_device_handle_impl.h"
22 #include "device/usb/usb_error.h" 23 #include "device/usb/usb_error.h"
23 #include "third_party/libusb/src/libusb/libusb.h" 24 #include "third_party/libusb/src/libusb/libusb.h"
24 25
26 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) || defined(OS_LINUX)
27 #include "device/usb/usb_device_handle_usbfs.h"
28 #else
29 #include "device/usb/usb_device_handle_impl.h"
30 #endif
31
25 #if defined(OS_CHROMEOS) 32 #if defined(OS_CHROMEOS)
26 #include "chromeos/dbus/dbus_thread_manager.h" 33 #include "chromeos/dbus/dbus_thread_manager.h"
27 #include "chromeos/dbus/permission_broker_client.h" 34 #include "chromeos/dbus/permission_broker_client.h"
28 #include "dbus/file_descriptor.h" // nogncheck 35 #include "dbus/file_descriptor.h" // nogncheck
29 #endif // defined(OS_CHROMEOS) 36 #endif // defined(OS_CHROMEOS)
30 37
31 namespace device { 38 namespace device {
32 39
33 namespace { 40 namespace {
34 41
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 device_path_, 201 device_path_,
195 base::Bind(&UsbDeviceImpl::OnOpenRequestComplete, this, callback), 202 base::Bind(&UsbDeviceImpl::OnOpenRequestComplete, this, callback),
196 base::Bind(&UsbDeviceImpl::OnOpenRequestError, this, callback)); 203 base::Bind(&UsbDeviceImpl::OnOpenRequestError, this, callback));
197 #else 204 #else
198 blocking_task_runner_->PostTask( 205 blocking_task_runner_->PostTask(
199 FROM_HERE, 206 FROM_HERE,
200 base::Bind(&UsbDeviceImpl::OpenOnBlockingThread, this, callback)); 207 base::Bind(&UsbDeviceImpl::OpenOnBlockingThread, this, callback));
201 #endif // defined(OS_CHROMEOS) 208 #endif // defined(OS_CHROMEOS)
202 } 209 }
203 210
204 void UsbDeviceImpl::HandleClosed(scoped_refptr<UsbDeviceHandle> handle) { 211 void UsbDeviceImpl::HandleClosed(UsbDeviceHandle* handle) {
205 DCHECK(thread_checker_.CalledOnValidThread()); 212 DCHECK(thread_checker_.CalledOnValidThread());
206 handles_.remove(handle.get()); 213 handles_.remove(handle);
207 } 214 }
208 215
209 const UsbConfigDescriptor* UsbDeviceImpl::GetActiveConfiguration() const { 216 const UsbConfigDescriptor* UsbDeviceImpl::GetActiveConfiguration() const {
210 DCHECK(thread_checker_.CalledOnValidThread()); 217 DCHECK(thread_checker_.CalledOnValidThread());
211 return active_configuration_; 218 return active_configuration_;
212 } 219 }
213 220
214 void UsbDeviceImpl::OnDisconnect() { 221 void UsbDeviceImpl::OnDisconnect() {
215 DCHECK(thread_checker_.CalledOnValidThread()); 222 DCHECK(thread_checker_.CalledOnValidThread());
216 // Swap out the handle list as HandleClosed() will try to modify it. 223 // Swap out the handle list as HandleClosed() will try to modify it.
(...skipping 26 matching lines...) Expand all
243 ConvertConfigDescriptor(platform_config, &config_descriptor); 250 ConvertConfigDescriptor(platform_config, &config_descriptor);
244 configurations_.push_back(config_descriptor); 251 configurations_.push_back(config_descriptor);
245 libusb_free_config_descriptor(platform_config); 252 libusb_free_config_descriptor(platform_config);
246 } 253 }
247 } else { 254 } else {
248 USB_LOG(EVENT) << "Failed to get device descriptor: " 255 USB_LOG(EVENT) << "Failed to get device descriptor: "
249 << ConvertPlatformUsbErrorToString(rv); 256 << ConvertPlatformUsbErrorToString(rv);
250 } 257 }
251 } 258 }
252 259
260 void UsbDeviceImpl::ActiveConfigurationChanged(int configuration_value) {
261 for (const auto& config : configurations_) {
262 if (config.configuration_value == configuration_value) {
263 active_configuration_ = &config;
264 break;
juncai 2016/04/13 00:31:10 may just use return; here.
265 }
266 }
267 }
268
253 void UsbDeviceImpl::RefreshActiveConfiguration() { 269 void UsbDeviceImpl::RefreshActiveConfiguration() {
254 active_configuration_ = nullptr; 270 active_configuration_ = nullptr;
255 libusb_config_descriptor* platform_config; 271 libusb_config_descriptor* platform_config;
256 int rv = 272 int rv =
257 libusb_get_active_config_descriptor(platform_device_, &platform_config); 273 libusb_get_active_config_descriptor(platform_device_, &platform_config);
258 if (rv != LIBUSB_SUCCESS) { 274 if (rv != LIBUSB_SUCCESS) {
259 USB_LOG(EVENT) << "Failed to get config descriptor: " 275 USB_LOG(EVENT) << "Failed to get config descriptor: "
260 << ConvertPlatformUsbErrorToString(rv); 276 << ConvertPlatformUsbErrorToString(rv);
261 return; 277 return;
262 } 278 }
263 279
264 for (const auto& config : configurations_) { 280 ActiveConfigurationChanged(platform_config->bConfigurationValue);
265 if (config.configuration_value == platform_config->bConfigurationValue) {
266 active_configuration_ = &config;
267 break;
268 }
269 }
270
271 libusb_free_config_descriptor(platform_config); 281 libusb_free_config_descriptor(platform_config);
272 } 282 }
273 283
274 #if defined(OS_CHROMEOS) 284 #if defined(OS_CHROMEOS)
275 285
276 void UsbDeviceImpl::OnOpenRequestComplete(const OpenCallback& callback, 286 void UsbDeviceImpl::OnOpenRequestComplete(const OpenCallback& callback,
277 dbus::FileDescriptor fd) { 287 dbus::FileDescriptor fd) {
278 blocking_task_runner_->PostTask( 288 blocking_task_runner_->PostTask(
279 FROM_HERE, base::Bind(&UsbDeviceImpl::OpenOnBlockingThreadWithFd, this, 289 FROM_HERE, base::Bind(&UsbDeviceImpl::OpenOnBlockingThreadWithFd, this,
280 base::Passed(&fd), callback)); 290 base::Passed(&fd), callback));
281 } 291 }
282 292
283 void UsbDeviceImpl::OnOpenRequestError(const OpenCallback& callback, 293 void UsbDeviceImpl::OnOpenRequestError(const OpenCallback& callback,
284 const std::string& error_name, 294 const std::string& error_name,
285 const std::string& error_message) { 295 const std::string& error_message) {
286 USB_LOG(EVENT) << "Permission broker failed to open the device: " 296 USB_LOG(EVENT) << "Permission broker failed to open the device: "
287 << error_name << ": " << error_message; 297 << error_name << ": " << error_message;
288 callback.Run(nullptr); 298 callback.Run(nullptr);
289 } 299 }
290 300
291 void UsbDeviceImpl::OpenOnBlockingThreadWithFd(dbus::FileDescriptor fd, 301 void UsbDeviceImpl::OpenOnBlockingThreadWithFd(dbus::FileDescriptor fd,
292 const OpenCallback& callback) { 302 const OpenCallback& callback) {
293 fd.CheckValidity(); 303 fd.CheckValidity();
294 DCHECK(fd.is_valid()); 304 if (fd.is_valid()) {
295 305 base::ScopedFD scoped_fd(fd.TakeValue());
296 PlatformUsbDeviceHandle handle; 306 task_runner_->PostTask(FROM_HERE,
297 const int rv = libusb_open_fd(platform_device_, fd.TakeValue(), &handle); 307 base::Bind(&UsbDeviceImpl::Opened, this,
298 if (LIBUSB_SUCCESS == rv) { 308 base::Passed(&scoped_fd), callback));
299 task_runner_->PostTask(
300 FROM_HERE, base::Bind(&UsbDeviceImpl::Opened, this, handle, callback));
301 } else { 309 } else {
302 USB_LOG(EVENT) << "Failed to open device: " 310 USB_LOG(EVENT) << "Did not get valid device handle from permission broker.";
303 << ConvertPlatformUsbErrorToString(rv);
304 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); 311 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr));
305 } 312 }
306 } 313 }
307 314
308 #endif // defined(OS_CHROMEOS) 315 #else
316 #if defined(OS_LINUX)
317
318 void UsbDeviceImpl::OpenOnBlockingThread(const OpenCallback& callback) {
319 base::ScopedFD fd(HANDLE_EINTR(open(device_path_.c_str(), O_RDWR)));
320 if (fd.is_valid()) {
321 task_runner_->PostTask(FROM_HERE, base::Bind(&UsbDeviceImpl::Opened, this,
322 base::Passed(&fd), callback));
323 } else {
324 USB_PLOG(EVENT) << "Failed to open device";
325 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr));
326 }
327 }
328
329 #else
309 330
310 void UsbDeviceImpl::OpenOnBlockingThread(const OpenCallback& callback) { 331 void UsbDeviceImpl::OpenOnBlockingThread(const OpenCallback& callback) {
311 PlatformUsbDeviceHandle handle; 332 PlatformUsbDeviceHandle handle;
312 const int rv = libusb_open(platform_device_, &handle); 333 const int rv = libusb_open(platform_device_, &handle);
313 if (LIBUSB_SUCCESS == rv) { 334 if (LIBUSB_SUCCESS == rv) {
314 task_runner_->PostTask( 335 task_runner_->PostTask(
315 FROM_HERE, base::Bind(&UsbDeviceImpl::Opened, this, handle, callback)); 336 FROM_HERE, base::Bind(&UsbDeviceImpl::Opened, this, handle, callback));
316 } else { 337 } else {
317 USB_LOG(EVENT) << "Failed to open device: " 338 USB_LOG(EVENT) << "Failed to open device: "
318 << ConvertPlatformUsbErrorToString(rv); 339 << ConvertPlatformUsbErrorToString(rv);
319 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr));
320 } 340 }
321 } 341 }
322 342
343 #endif // defined(OS_LINUX)
344 #endif // defined(OS_CHROMEOS)
345
346 #if defined(OS_LINUX)
347
348 void UsbDeviceImpl::Opened(base::ScopedFD fd, const OpenCallback& callback) {
349 DCHECK(thread_checker_.CalledOnValidThread());
350 scoped_refptr<UsbDeviceHandle> device_handle =
351 new UsbDeviceHandleUsbfs(this, std::move(fd), blocking_task_runner_);
352 handles_.push_back(device_handle.get());
353 callback.Run(device_handle);
354 }
355
356 #else
357
323 void UsbDeviceImpl::Opened(PlatformUsbDeviceHandle platform_handle, 358 void UsbDeviceImpl::Opened(PlatformUsbDeviceHandle platform_handle,
324 const OpenCallback& callback) { 359 const OpenCallback& callback) {
325 DCHECK(thread_checker_.CalledOnValidThread()); 360 DCHECK(thread_checker_.CalledOnValidThread());
326 scoped_refptr<UsbDeviceHandleImpl> device_handle = new UsbDeviceHandleImpl( 361 scoped_refptr<UsbDeviceHandle> device_handle = new UsbDeviceHandleImpl(
327 context_, this, platform_handle, blocking_task_runner_); 362 context_, this, platform_handle, blocking_task_runner_);
328 handles_.push_back(device_handle.get()); 363 handles_.push_back(device_handle.get());
329 callback.Run(device_handle); 364 callback.Run(device_handle);
330 } 365 }
331 366
367 #endif // defined(OS_LINUX)
368
332 } // namespace device 369 } // namespace device
OLDNEW
« device/usb/usb_device_handle_usbfs.cc ('K') | « device/usb/usb_device_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698