OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/mojo/device_impl.h" | 5 #include "device/usb/mojo/device_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
(...skipping 14 matching lines...) Expand all Loading... |
25 namespace device { | 25 namespace device { |
26 namespace usb { | 26 namespace usb { |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 scoped_refptr<net::IOBuffer> CreateTransferBuffer(size_t size) { | 30 scoped_refptr<net::IOBuffer> CreateTransferBuffer(size_t size) { |
31 return new net::IOBuffer( | 31 return new net::IOBuffer( |
32 std::max(static_cast<size_t>(1u), static_cast<size_t>(size))); | 32 std::max(static_cast<size_t>(1u), static_cast<size_t>(size))); |
33 } | 33 } |
34 | 34 |
35 void OnTransferIn(std::unique_ptr<Device::GenericTransferInCallback> callback, | 35 void OnTransferIn(const Device::GenericTransferInCallback& callback, |
36 UsbTransferStatus status, | 36 UsbTransferStatus status, |
37 scoped_refptr<net::IOBuffer> buffer, | 37 scoped_refptr<net::IOBuffer> buffer, |
38 size_t buffer_size) { | 38 size_t buffer_size) { |
39 std::vector<uint8_t> data; | 39 std::vector<uint8_t> data; |
40 if (buffer) { | 40 if (buffer) { |
41 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a | 41 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a |
42 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move | 42 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move |
43 // instead of copy. | 43 // instead of copy. |
44 data.resize(buffer_size); | 44 data.resize(buffer_size); |
45 std::copy(buffer->data(), buffer->data() + buffer_size, data.begin()); | 45 std::copy(buffer->data(), buffer->data() + buffer_size, data.begin()); |
46 } | 46 } |
47 callback->Run(mojo::ConvertTo<TransferStatus>(status), data); | 47 |
| 48 callback.Run(mojo::ConvertTo<TransferStatus>(status), data); |
48 } | 49 } |
49 | 50 |
50 void OnTransferOut(std::unique_ptr<Device::GenericTransferOutCallback> callback, | 51 void OnTransferOut(const Device::GenericTransferOutCallback& callback, |
51 UsbTransferStatus status, | 52 UsbTransferStatus status, |
52 scoped_refptr<net::IOBuffer> buffer, | 53 scoped_refptr<net::IOBuffer> buffer, |
53 size_t buffer_size) { | 54 size_t buffer_size) { |
54 callback->Run(mojo::ConvertTo<TransferStatus>(status)); | 55 callback.Run(mojo::ConvertTo<TransferStatus>(status)); |
55 } | 56 } |
56 | 57 |
57 std::vector<IsochronousPacketPtr> BuildIsochronousPacketArray( | 58 std::vector<IsochronousPacketPtr> BuildIsochronousPacketArray( |
58 const std::vector<uint32_t>& packet_lengths, | 59 const std::vector<uint32_t>& packet_lengths, |
59 TransferStatus status) { | 60 TransferStatus status) { |
60 std::vector<IsochronousPacketPtr> packets; | 61 std::vector<IsochronousPacketPtr> packets; |
61 packets.reserve(packet_lengths.size()); | 62 packets.reserve(packet_lengths.size()); |
62 for (uint32_t packet_length : packet_lengths) { | 63 for (uint32_t packet_length : packet_lengths) { |
63 auto packet = IsochronousPacket::New(); | 64 auto packet = IsochronousPacket::New(); |
64 packet->length = packet_length; | 65 packet->length = packet_length; |
65 packet->status = status; | 66 packet->status = status; |
66 packets.push_back(std::move(packet)); | 67 packets.push_back(std::move(packet)); |
67 } | 68 } |
68 return packets; | 69 return packets; |
69 } | 70 } |
70 | 71 |
71 void OnIsochronousTransferIn( | 72 void OnIsochronousTransferIn( |
72 std::unique_ptr<Device::IsochronousTransferInCallback> callback, | 73 const Device::IsochronousTransferInCallback& callback, |
73 scoped_refptr<net::IOBuffer> buffer, | 74 scoped_refptr<net::IOBuffer> buffer, |
74 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { | 75 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { |
75 std::vector<uint8_t> data; | 76 std::vector<uint8_t> data; |
76 if (buffer) { | 77 if (buffer) { |
77 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a | 78 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a |
78 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move | 79 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move |
79 // instead of copy. | 80 // instead of copy. |
80 uint32_t buffer_size = | 81 uint32_t buffer_size = |
81 std::accumulate(packets.begin(), packets.end(), 0u, | 82 std::accumulate(packets.begin(), packets.end(), 0u, |
82 [](const uint32_t& a, | 83 [](const uint32_t& a, |
83 const UsbDeviceHandle::IsochronousPacket& packet) { | 84 const UsbDeviceHandle::IsochronousPacket& packet) { |
84 return a + packet.length; | 85 return a + packet.length; |
85 }); | 86 }); |
86 data.resize(buffer_size); | 87 data.resize(buffer_size); |
87 std::copy(buffer->data(), buffer->data() + buffer_size, data.begin()); | 88 std::copy(buffer->data(), buffer->data() + buffer_size, data.begin()); |
88 } | 89 } |
89 | 90 callback.Run(data, |
90 callback->Run(data, | 91 mojo::ConvertTo<std::vector<IsochronousPacketPtr>>(packets)); |
91 mojo::ConvertTo<std::vector<IsochronousPacketPtr>>(packets)); | |
92 } | 92 } |
93 | 93 |
94 void OnIsochronousTransferOut( | 94 void OnIsochronousTransferOut( |
95 std::unique_ptr<Device::IsochronousTransferOutCallback> callback, | 95 const Device::IsochronousTransferOutCallback& callback, |
96 scoped_refptr<net::IOBuffer> buffer, | 96 scoped_refptr<net::IOBuffer> buffer, |
97 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { | 97 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { |
98 callback->Run(mojo::ConvertTo<std::vector<IsochronousPacketPtr>>(packets)); | 98 callback.Run(mojo::ConvertTo<std::vector<IsochronousPacketPtr>>(packets)); |
99 } | 99 } |
100 | 100 |
101 } // namespace | 101 } // namespace |
102 | 102 |
103 DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device, | 103 DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device, |
104 DeviceInfoPtr device_info, | 104 DeviceInfoPtr device_info, |
105 base::WeakPtr<PermissionProvider> permission_provider, | 105 base::WeakPtr<PermissionProvider> permission_provider, |
106 mojo::InterfaceRequest<Device> request) | 106 mojo::InterfaceRequest<Device> request) |
107 : device_(device), | 107 : device_(device), |
108 device_info_(std::move(device_info)), | 108 device_info_(std::move(device_info)), |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 uint32_t length, | 317 uint32_t length, |
318 uint32_t timeout, | 318 uint32_t timeout, |
319 const ControlTransferInCallback& callback) { | 319 const ControlTransferInCallback& callback) { |
320 if (!device_handle_) { | 320 if (!device_handle_) { |
321 callback.Run(TransferStatus::TRANSFER_ERROR, base::nullopt); | 321 callback.Run(TransferStatus::TRANSFER_ERROR, base::nullopt); |
322 return; | 322 return; |
323 } | 323 } |
324 | 324 |
325 if (HasControlTransferPermission(params->recipient, params->index)) { | 325 if (HasControlTransferPermission(params->recipient, params->index)) { |
326 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); | 326 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); |
327 auto callback_ptr = | |
328 base::WrapUnique(new ControlTransferInCallback(callback)); | |
329 device_handle_->ControlTransfer( | 327 device_handle_->ControlTransfer( |
330 USB_DIRECTION_INBOUND, | 328 USB_DIRECTION_INBOUND, |
331 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), | 329 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), |
332 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), | 330 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), |
333 params->request, params->value, params->index, buffer, length, timeout, | 331 params->request, params->value, params->index, buffer, length, timeout, |
334 base::Bind(&OnTransferIn, base::Passed(&callback_ptr))); | 332 base::Bind(&OnTransferIn, callback)); |
335 } else { | 333 } else { |
336 callback.Run(TransferStatus::PERMISSION_DENIED, base::nullopt); | 334 callback.Run(TransferStatus::PERMISSION_DENIED, base::nullopt); |
337 } | 335 } |
338 } | 336 } |
339 | 337 |
340 void DeviceImpl::ControlTransferOut( | 338 void DeviceImpl::ControlTransferOut( |
341 ControlTransferParamsPtr params, | 339 ControlTransferParamsPtr params, |
342 const std::vector<uint8_t>& data, | 340 const std::vector<uint8_t>& data, |
343 uint32_t timeout, | 341 uint32_t timeout, |
344 const ControlTransferOutCallback& callback) { | 342 const ControlTransferOutCallback& callback) { |
345 if (!device_handle_) { | 343 if (!device_handle_) { |
346 callback.Run(TransferStatus::TRANSFER_ERROR); | 344 callback.Run(TransferStatus::TRANSFER_ERROR); |
347 return; | 345 return; |
348 } | 346 } |
349 | 347 |
350 if (HasControlTransferPermission(params->recipient, params->index)) { | 348 if (HasControlTransferPermission(params->recipient, params->index)) { |
351 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); | 349 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); |
352 std::copy(data.begin(), data.end(), buffer->data()); | 350 std::copy(data.begin(), data.end(), buffer->data()); |
353 auto callback_ptr = | |
354 base::WrapUnique(new ControlTransferOutCallback(callback)); | |
355 device_handle_->ControlTransfer( | 351 device_handle_->ControlTransfer( |
356 USB_DIRECTION_OUTBOUND, | 352 USB_DIRECTION_OUTBOUND, |
357 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), | 353 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), |
358 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), | 354 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), |
359 params->request, params->value, params->index, buffer, data.size(), | 355 params->request, params->value, params->index, buffer, data.size(), |
360 timeout, base::Bind(&OnTransferOut, base::Passed(&callback_ptr))); | 356 timeout, base::Bind(&OnTransferOut, callback)); |
361 } else { | 357 } else { |
362 callback.Run(TransferStatus::PERMISSION_DENIED); | 358 callback.Run(TransferStatus::PERMISSION_DENIED); |
363 } | 359 } |
364 } | 360 } |
365 | 361 |
366 void DeviceImpl::GenericTransferIn(uint8_t endpoint_number, | 362 void DeviceImpl::GenericTransferIn(uint8_t endpoint_number, |
367 uint32_t length, | 363 uint32_t length, |
368 uint32_t timeout, | 364 uint32_t timeout, |
369 const GenericTransferInCallback& callback) { | 365 const GenericTransferInCallback& callback) { |
370 if (!device_handle_) { | 366 if (!device_handle_) { |
371 callback.Run(TransferStatus::TRANSFER_ERROR, base::nullopt); | 367 callback.Run(TransferStatus::TRANSFER_ERROR, base::nullopt); |
372 return; | 368 return; |
373 } | 369 } |
374 | 370 |
375 auto callback_ptr = base::WrapUnique(new GenericTransferInCallback(callback)); | |
376 uint8_t endpoint_address = endpoint_number | 0x80; | 371 uint8_t endpoint_address = endpoint_number | 0x80; |
377 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); | 372 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); |
378 device_handle_->GenericTransfer( | 373 device_handle_->GenericTransfer(USB_DIRECTION_INBOUND, endpoint_address, |
379 USB_DIRECTION_INBOUND, endpoint_address, buffer, length, timeout, | 374 buffer, length, timeout, |
380 base::Bind(&OnTransferIn, base::Passed(&callback_ptr))); | 375 base::Bind(&OnTransferIn, callback)); |
381 } | 376 } |
382 | 377 |
383 void DeviceImpl::GenericTransferOut( | 378 void DeviceImpl::GenericTransferOut( |
384 uint8_t endpoint_number, | 379 uint8_t endpoint_number, |
385 const std::vector<uint8_t>& data, | 380 const std::vector<uint8_t>& data, |
386 uint32_t timeout, | 381 uint32_t timeout, |
387 const GenericTransferOutCallback& callback) { | 382 const GenericTransferOutCallback& callback) { |
388 if (!device_handle_) { | 383 if (!device_handle_) { |
389 callback.Run(TransferStatus::TRANSFER_ERROR); | 384 callback.Run(TransferStatus::TRANSFER_ERROR); |
390 return; | 385 return; |
391 } | 386 } |
392 | 387 |
393 auto callback_ptr = | |
394 base::WrapUnique(new GenericTransferOutCallback(callback)); | |
395 uint8_t endpoint_address = endpoint_number; | 388 uint8_t endpoint_address = endpoint_number; |
396 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); | 389 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); |
397 std::copy(data.begin(), data.end(), buffer->data()); | 390 std::copy(data.begin(), data.end(), buffer->data()); |
398 device_handle_->GenericTransfer( | 391 device_handle_->GenericTransfer(USB_DIRECTION_OUTBOUND, endpoint_address, |
399 USB_DIRECTION_OUTBOUND, endpoint_address, buffer, data.size(), timeout, | 392 buffer, data.size(), timeout, |
400 base::Bind(&OnTransferOut, base::Passed(&callback_ptr))); | 393 base::Bind(&OnTransferOut, callback)); |
401 } | 394 } |
402 | 395 |
403 void DeviceImpl::IsochronousTransferIn( | 396 void DeviceImpl::IsochronousTransferIn( |
404 uint8_t endpoint_number, | 397 uint8_t endpoint_number, |
405 const std::vector<uint32_t>& packet_lengths, | 398 const std::vector<uint32_t>& packet_lengths, |
406 uint32_t timeout, | 399 uint32_t timeout, |
407 const IsochronousTransferInCallback& callback) { | 400 const IsochronousTransferInCallback& callback) { |
408 if (!device_handle_) { | 401 if (!device_handle_) { |
409 callback.Run(base::nullopt, | 402 callback.Run(base::nullopt, |
410 BuildIsochronousPacketArray(packet_lengths, | 403 BuildIsochronousPacketArray(packet_lengths, |
411 TransferStatus::TRANSFER_ERROR)); | 404 TransferStatus::TRANSFER_ERROR)); |
412 return; | 405 return; |
413 } | 406 } |
414 | 407 |
415 auto callback_ptr = | |
416 base::WrapUnique(new IsochronousTransferInCallback(callback)); | |
417 uint8_t endpoint_address = endpoint_number | 0x80; | 408 uint8_t endpoint_address = endpoint_number | 0x80; |
418 device_handle_->IsochronousTransferIn( | 409 device_handle_->IsochronousTransferIn( |
419 endpoint_address, packet_lengths, timeout, | 410 endpoint_address, packet_lengths, timeout, |
420 base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr))); | 411 base::Bind(&OnIsochronousTransferIn, callback)); |
421 } | 412 } |
422 | 413 |
423 void DeviceImpl::IsochronousTransferOut( | 414 void DeviceImpl::IsochronousTransferOut( |
424 uint8_t endpoint_number, | 415 uint8_t endpoint_number, |
425 const std::vector<uint8_t>& data, | 416 const std::vector<uint8_t>& data, |
426 const std::vector<uint32_t>& packet_lengths, | 417 const std::vector<uint32_t>& packet_lengths, |
427 uint32_t timeout, | 418 uint32_t timeout, |
428 const IsochronousTransferOutCallback& callback) { | 419 const IsochronousTransferOutCallback& callback) { |
429 if (!device_handle_) { | 420 if (!device_handle_) { |
430 callback.Run(BuildIsochronousPacketArray(packet_lengths, | 421 callback.Run(BuildIsochronousPacketArray(packet_lengths, |
431 TransferStatus::TRANSFER_ERROR)); | 422 TransferStatus::TRANSFER_ERROR)); |
432 return; | 423 return; |
433 } | 424 } |
434 | 425 |
435 auto callback_ptr = | |
436 base::WrapUnique(new IsochronousTransferOutCallback(callback)); | |
437 uint8_t endpoint_address = endpoint_number; | 426 uint8_t endpoint_address = endpoint_number; |
438 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); | 427 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); |
439 std::copy(data.begin(), data.end(), buffer->data()); | 428 std::copy(data.begin(), data.end(), buffer->data()); |
440 device_handle_->IsochronousTransferOut( | 429 device_handle_->IsochronousTransferOut( |
441 endpoint_address, buffer, packet_lengths, timeout, | 430 endpoint_address, buffer, packet_lengths, timeout, |
442 base::Bind(&OnIsochronousTransferOut, base::Passed(&callback_ptr))); | 431 base::Bind(&OnIsochronousTransferOut, callback)); |
443 } | 432 } |
444 | 433 |
445 void DeviceImpl::OnDeviceRemoved(scoped_refptr<UsbDevice> device) { | 434 void DeviceImpl::OnDeviceRemoved(scoped_refptr<UsbDevice> device) { |
446 DCHECK_EQ(device_, device); | 435 DCHECK_EQ(device_, device); |
447 delete this; | 436 delete this; |
448 } | 437 } |
449 | 438 |
450 } // namespace usb | 439 } // namespace usb |
451 } // namespace device | 440 } // namespace device |
OLD | NEW |