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

Side by Side Diff: device/usb/mojo/device_impl.cc

Issue 1874313002: Convert device to std::unique_ptr (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
« no previous file with comments | « device/udev_linux/udev_loader.cc ('k') | device/usb/mojo/device_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <numeric> 11 #include <numeric>
11 #include <utility> 12 #include <utility>
12 #include <vector> 13 #include <vector>
13 14
14 #include "base/bind.h" 15 #include "base/bind.h"
15 #include "base/callback.h" 16 #include "base/callback.h"
17 #include "base/memory/ptr_util.h"
16 #include "base/stl_util.h" 18 #include "base/stl_util.h"
17 #include "device/usb/mojo/type_converters.h" 19 #include "device/usb/mojo/type_converters.h"
18 #include "device/usb/usb_descriptors.h" 20 #include "device/usb/usb_descriptors.h"
19 #include "device/usb/usb_device.h" 21 #include "device/usb/usb_device.h"
20 #include "net/base/io_buffer.h" 22 #include "net/base/io_buffer.h"
21 23
22 namespace device { 24 namespace device {
23 namespace usb { 25 namespace usb {
24 26
25 namespace { 27 namespace {
26 28
27 using MojoTransferInCallback = 29 using MojoTransferInCallback =
28 mojo::Callback<void(TransferStatus, mojo::Array<uint8_t>)>; 30 mojo::Callback<void(TransferStatus, mojo::Array<uint8_t>)>;
29 31
30 using MojoTransferOutCallback = mojo::Callback<void(TransferStatus)>; 32 using MojoTransferOutCallback = mojo::Callback<void(TransferStatus)>;
31 33
32 template <typename... Args> 34 template <typename... Args>
33 void CallMojoCallback(scoped_ptr<mojo::Callback<void(Args...)>> callback, 35 void CallMojoCallback(std::unique_ptr<mojo::Callback<void(Args...)>> callback,
34 Args... args) { 36 Args... args) {
35 callback->Run(args...); 37 callback->Run(args...);
36 } 38 }
37 39
38 // Generic wrapper to convert a Mojo callback to something we can rebind and 40 // Generic wrapper to convert a Mojo callback to something we can rebind and
39 // pass around. This is only usable for callbacks with no move-only arguments. 41 // pass around. This is only usable for callbacks with no move-only arguments.
40 template <typename... Args> 42 template <typename... Args>
41 base::Callback<void(Args...)> WrapMojoCallback( 43 base::Callback<void(Args...)> WrapMojoCallback(
42 const mojo::Callback<void(Args...)>& callback) { 44 const mojo::Callback<void(Args...)>& callback) {
43 // mojo::Callback is not thread safe. By wrapping |callback| in a scoped_ptr 45 // mojo::Callback is not thread safe. By wrapping |callback| in a scoped_ptr
44 // we guarantee that it will be freed when CallMojoCallback is run and not 46 // we guarantee that it will be freed when CallMojoCallback is run and not
45 // retained until the base::Callback is destroyed, which could happen on any 47 // retained until the base::Callback is destroyed, which could happen on any
46 // thread. This pattern is also used below in places where this generic 48 // thread. This pattern is also used below in places where this generic
47 // wrapper is not used. 49 // wrapper is not used.
48 auto callback_ptr = 50 auto callback_ptr =
49 make_scoped_ptr(new mojo::Callback<void(Args...)>(callback)); 51 base::WrapUnique(new mojo::Callback<void(Args...)>(callback));
50 return base::Bind(&CallMojoCallback<Args...>, base::Passed(&callback_ptr)); 52 return base::Bind(&CallMojoCallback<Args...>, base::Passed(&callback_ptr));
51 } 53 }
52 54
53 scoped_refptr<net::IOBuffer> CreateTransferBuffer(size_t size) { 55 scoped_refptr<net::IOBuffer> CreateTransferBuffer(size_t size) {
54 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer( 56 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(
55 std::max(static_cast<size_t>(1u), static_cast<size_t>(size))); 57 std::max(static_cast<size_t>(1u), static_cast<size_t>(size)));
56 return buffer; 58 return buffer;
57 } 59 }
58 60
59 void OnTransferIn(scoped_ptr<MojoTransferInCallback> callback, 61 void OnTransferIn(std::unique_ptr<MojoTransferInCallback> callback,
60 UsbTransferStatus status, 62 UsbTransferStatus status,
61 scoped_refptr<net::IOBuffer> buffer, 63 scoped_refptr<net::IOBuffer> buffer,
62 size_t buffer_size) { 64 size_t buffer_size) {
63 mojo::Array<uint8_t> data; 65 mojo::Array<uint8_t> data;
64 if (buffer) { 66 if (buffer) {
65 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a 67 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a
66 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move 68 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move
67 // instead of copy. 69 // instead of copy.
68 std::vector<uint8_t> bytes(buffer_size); 70 std::vector<uint8_t> bytes(buffer_size);
69 std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin()); 71 std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin());
70 data.Swap(&bytes); 72 data.Swap(&bytes);
71 } 73 }
72 callback->Run(mojo::ConvertTo<TransferStatus>(status), std::move(data)); 74 callback->Run(mojo::ConvertTo<TransferStatus>(status), std::move(data));
73 } 75 }
74 76
75 void OnTransferOut(scoped_ptr<MojoTransferOutCallback> callback, 77 void OnTransferOut(std::unique_ptr<MojoTransferOutCallback> callback,
76 UsbTransferStatus status, 78 UsbTransferStatus status,
77 scoped_refptr<net::IOBuffer> buffer, 79 scoped_refptr<net::IOBuffer> buffer,
78 size_t buffer_size) { 80 size_t buffer_size) {
79 callback->Run(mojo::ConvertTo<TransferStatus>(status)); 81 callback->Run(mojo::ConvertTo<TransferStatus>(status));
80 } 82 }
81 83
82 mojo::Array<IsochronousPacketPtr> BuildIsochronousPacketArray( 84 mojo::Array<IsochronousPacketPtr> BuildIsochronousPacketArray(
83 mojo::Array<uint32_t> packet_lengths, 85 mojo::Array<uint32_t> packet_lengths,
84 TransferStatus status) { 86 TransferStatus status) {
85 mojo::Array<IsochronousPacketPtr> packets(packet_lengths.size()); 87 mojo::Array<IsochronousPacketPtr> packets(packet_lengths.size());
86 for (size_t i = 0; i < packet_lengths.size(); ++i) { 88 for (size_t i = 0; i < packet_lengths.size(); ++i) {
87 packets[i] = IsochronousPacket::New(); 89 packets[i] = IsochronousPacket::New();
88 packets[i]->length = packet_lengths[i]; 90 packets[i]->length = packet_lengths[i];
89 packets[i]->status = status; 91 packets[i]->status = status;
90 } 92 }
91 return packets; 93 return packets;
92 } 94 }
93 95
94 void OnIsochronousTransferIn( 96 void OnIsochronousTransferIn(
95 scoped_ptr<Device::IsochronousTransferInCallback> callback, 97 std::unique_ptr<Device::IsochronousTransferInCallback> callback,
96 scoped_refptr<net::IOBuffer> buffer, 98 scoped_refptr<net::IOBuffer> buffer,
97 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { 99 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) {
98 mojo::Array<uint8_t> data; 100 mojo::Array<uint8_t> data;
99 if (buffer) { 101 if (buffer) {
100 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a 102 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a
101 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move 103 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move
102 // instead of copy. 104 // instead of copy.
103 uint32_t buffer_size = 105 uint32_t buffer_size =
104 std::accumulate(packets.begin(), packets.end(), 0u, 106 std::accumulate(packets.begin(), packets.end(), 0u,
105 [](const uint32_t& a, 107 [](const uint32_t& a,
106 const UsbDeviceHandle::IsochronousPacket& packet) { 108 const UsbDeviceHandle::IsochronousPacket& packet) {
107 return a + packet.length; 109 return a + packet.length;
108 }); 110 });
109 std::vector<uint8_t> bytes(buffer_size); 111 std::vector<uint8_t> bytes(buffer_size);
110 std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin()); 112 std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin());
111 data.Swap(&bytes); 113 data.Swap(&bytes);
112 } 114 }
113 callback->Run(std::move(data), 115 callback->Run(std::move(data),
114 mojo::Array<IsochronousPacketPtr>::From(packets)); 116 mojo::Array<IsochronousPacketPtr>::From(packets));
115 } 117 }
116 118
117 void OnIsochronousTransferOut( 119 void OnIsochronousTransferOut(
118 scoped_ptr<Device::IsochronousTransferOutCallback> callback, 120 std::unique_ptr<Device::IsochronousTransferOutCallback> callback,
119 scoped_refptr<net::IOBuffer> buffer, 121 scoped_refptr<net::IOBuffer> buffer,
120 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { 122 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) {
121 callback->Run(mojo::Array<IsochronousPacketPtr>::From(packets)); 123 callback->Run(mojo::Array<IsochronousPacketPtr>::From(packets));
122 } 124 }
123 125
124 } // namespace 126 } // namespace
125 127
126 DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device, 128 DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device,
127 DeviceInfoPtr device_info, 129 DeviceInfoPtr device_info,
128 base::WeakPtr<PermissionProvider> permission_provider, 130 base::WeakPtr<PermissionProvider> permission_provider,
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 uint32_t timeout, 320 uint32_t timeout,
319 const ControlTransferInCallback& callback) { 321 const ControlTransferInCallback& callback) {
320 if (!device_handle_) { 322 if (!device_handle_) {
321 callback.Run(TransferStatus::TRANSFER_ERROR, mojo::Array<uint8_t>()); 323 callback.Run(TransferStatus::TRANSFER_ERROR, mojo::Array<uint8_t>());
322 return; 324 return;
323 } 325 }
324 326
325 if (HasControlTransferPermission(params->recipient, params->index)) { 327 if (HasControlTransferPermission(params->recipient, params->index)) {
326 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); 328 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length);
327 auto callback_ptr = 329 auto callback_ptr =
328 make_scoped_ptr(new ControlTransferInCallback(callback)); 330 base::WrapUnique(new ControlTransferInCallback(callback));
329 device_handle_->ControlTransfer( 331 device_handle_->ControlTransfer(
330 USB_DIRECTION_INBOUND, 332 USB_DIRECTION_INBOUND,
331 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), 333 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type),
332 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), 334 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient),
333 params->request, params->value, params->index, buffer, length, timeout, 335 params->request, params->value, params->index, buffer, length, timeout,
334 base::Bind(&OnTransferIn, base::Passed(&callback_ptr))); 336 base::Bind(&OnTransferIn, base::Passed(&callback_ptr)));
335 } else { 337 } else {
336 mojo::Array<uint8_t> data; 338 mojo::Array<uint8_t> data;
337 callback.Run(TransferStatus::PERMISSION_DENIED, std::move(data)); 339 callback.Run(TransferStatus::PERMISSION_DENIED, std::move(data));
338 } 340 }
339 } 341 }
340 342
341 void DeviceImpl::ControlTransferOut( 343 void DeviceImpl::ControlTransferOut(
342 ControlTransferParamsPtr params, 344 ControlTransferParamsPtr params,
343 mojo::Array<uint8_t> data, 345 mojo::Array<uint8_t> data,
344 uint32_t timeout, 346 uint32_t timeout,
345 const ControlTransferOutCallback& callback) { 347 const ControlTransferOutCallback& callback) {
346 if (!device_handle_) { 348 if (!device_handle_) {
347 callback.Run(TransferStatus::TRANSFER_ERROR); 349 callback.Run(TransferStatus::TRANSFER_ERROR);
348 return; 350 return;
349 } 351 }
350 352
351 if (HasControlTransferPermission(params->recipient, params->index)) { 353 if (HasControlTransferPermission(params->recipient, params->index)) {
352 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); 354 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size());
353 const std::vector<uint8_t>& storage = data.storage(); 355 const std::vector<uint8_t>& storage = data.storage();
354 std::copy(storage.begin(), storage.end(), buffer->data()); 356 std::copy(storage.begin(), storage.end(), buffer->data());
355 auto callback_ptr = 357 auto callback_ptr =
356 make_scoped_ptr(new ControlTransferOutCallback(callback)); 358 base::WrapUnique(new ControlTransferOutCallback(callback));
357 device_handle_->ControlTransfer( 359 device_handle_->ControlTransfer(
358 USB_DIRECTION_OUTBOUND, 360 USB_DIRECTION_OUTBOUND,
359 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), 361 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type),
360 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), 362 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient),
361 params->request, params->value, params->index, buffer, data.size(), 363 params->request, params->value, params->index, buffer, data.size(),
362 timeout, base::Bind(&OnTransferOut, base::Passed(&callback_ptr))); 364 timeout, base::Bind(&OnTransferOut, base::Passed(&callback_ptr)));
363 } else { 365 } else {
364 callback.Run(TransferStatus::PERMISSION_DENIED); 366 callback.Run(TransferStatus::PERMISSION_DENIED);
365 } 367 }
366 } 368 }
367 369
368 void DeviceImpl::GenericTransferIn(uint8_t endpoint_number, 370 void DeviceImpl::GenericTransferIn(uint8_t endpoint_number,
369 uint32_t length, 371 uint32_t length,
370 uint32_t timeout, 372 uint32_t timeout,
371 const GenericTransferInCallback& callback) { 373 const GenericTransferInCallback& callback) {
372 if (!device_handle_) { 374 if (!device_handle_) {
373 callback.Run(TransferStatus::TRANSFER_ERROR, mojo::Array<uint8_t>()); 375 callback.Run(TransferStatus::TRANSFER_ERROR, mojo::Array<uint8_t>());
374 return; 376 return;
375 } 377 }
376 378
377 auto callback_ptr = make_scoped_ptr(new GenericTransferInCallback(callback)); 379 auto callback_ptr = base::WrapUnique(new GenericTransferInCallback(callback));
378 uint8_t endpoint_address = endpoint_number | 0x80; 380 uint8_t endpoint_address = endpoint_number | 0x80;
379 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); 381 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length);
380 device_handle_->GenericTransfer( 382 device_handle_->GenericTransfer(
381 USB_DIRECTION_INBOUND, endpoint_address, buffer, length, timeout, 383 USB_DIRECTION_INBOUND, endpoint_address, buffer, length, timeout,
382 base::Bind(&OnTransferIn, base::Passed(&callback_ptr))); 384 base::Bind(&OnTransferIn, base::Passed(&callback_ptr)));
383 } 385 }
384 386
385 void DeviceImpl::GenericTransferOut( 387 void DeviceImpl::GenericTransferOut(
386 uint8_t endpoint_number, 388 uint8_t endpoint_number,
387 mojo::Array<uint8_t> data, 389 mojo::Array<uint8_t> data,
388 uint32_t timeout, 390 uint32_t timeout,
389 const GenericTransferOutCallback& callback) { 391 const GenericTransferOutCallback& callback) {
390 if (!device_handle_) { 392 if (!device_handle_) {
391 callback.Run(TransferStatus::TRANSFER_ERROR); 393 callback.Run(TransferStatus::TRANSFER_ERROR);
392 return; 394 return;
393 } 395 }
394 396
395 auto callback_ptr = make_scoped_ptr(new GenericTransferOutCallback(callback)); 397 auto callback_ptr =
398 base::WrapUnique(new GenericTransferOutCallback(callback));
396 uint8_t endpoint_address = endpoint_number; 399 uint8_t endpoint_address = endpoint_number;
397 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); 400 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size());
398 const std::vector<uint8_t>& storage = data.storage(); 401 const std::vector<uint8_t>& storage = data.storage();
399 std::copy(storage.begin(), storage.end(), buffer->data()); 402 std::copy(storage.begin(), storage.end(), buffer->data());
400 device_handle_->GenericTransfer( 403 device_handle_->GenericTransfer(
401 USB_DIRECTION_OUTBOUND, endpoint_address, buffer, data.size(), timeout, 404 USB_DIRECTION_OUTBOUND, endpoint_address, buffer, data.size(), timeout,
402 base::Bind(&OnTransferOut, base::Passed(&callback_ptr))); 405 base::Bind(&OnTransferOut, base::Passed(&callback_ptr)));
403 } 406 }
404 407
405 void DeviceImpl::IsochronousTransferIn( 408 void DeviceImpl::IsochronousTransferIn(
406 uint8_t endpoint_number, 409 uint8_t endpoint_number,
407 mojo::Array<uint32_t> packet_lengths, 410 mojo::Array<uint32_t> packet_lengths,
408 uint32_t timeout, 411 uint32_t timeout,
409 const IsochronousTransferInCallback& callback) { 412 const IsochronousTransferInCallback& callback) {
410 if (!device_handle_) { 413 if (!device_handle_) {
411 callback.Run(mojo::Array<uint8_t>(), 414 callback.Run(mojo::Array<uint8_t>(),
412 BuildIsochronousPacketArray(std::move(packet_lengths), 415 BuildIsochronousPacketArray(std::move(packet_lengths),
413 TransferStatus::TRANSFER_ERROR)); 416 TransferStatus::TRANSFER_ERROR));
414 return; 417 return;
415 } 418 }
416 419
417 auto callback_ptr = 420 auto callback_ptr =
418 make_scoped_ptr(new IsochronousTransferInCallback(callback)); 421 base::WrapUnique(new IsochronousTransferInCallback(callback));
419 uint8_t endpoint_address = endpoint_number | 0x80; 422 uint8_t endpoint_address = endpoint_number | 0x80;
420 device_handle_->IsochronousTransferIn( 423 device_handle_->IsochronousTransferIn(
421 endpoint_address, packet_lengths.storage(), timeout, 424 endpoint_address, packet_lengths.storage(), timeout,
422 base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr))); 425 base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr)));
423 } 426 }
424 427
425 void DeviceImpl::IsochronousTransferOut( 428 void DeviceImpl::IsochronousTransferOut(
426 uint8_t endpoint_number, 429 uint8_t endpoint_number,
427 mojo::Array<uint8_t> data, 430 mojo::Array<uint8_t> data,
428 mojo::Array<uint32_t> packet_lengths, 431 mojo::Array<uint32_t> packet_lengths,
429 uint32_t timeout, 432 uint32_t timeout,
430 const IsochronousTransferOutCallback& callback) { 433 const IsochronousTransferOutCallback& callback) {
431 if (!device_handle_) { 434 if (!device_handle_) {
432 callback.Run(BuildIsochronousPacketArray(std::move(packet_lengths), 435 callback.Run(BuildIsochronousPacketArray(std::move(packet_lengths),
433 TransferStatus::TRANSFER_ERROR)); 436 TransferStatus::TRANSFER_ERROR));
434 return; 437 return;
435 } 438 }
436 439
437 auto callback_ptr = 440 auto callback_ptr =
438 make_scoped_ptr(new IsochronousTransferOutCallback(callback)); 441 base::WrapUnique(new IsochronousTransferOutCallback(callback));
439 uint8_t endpoint_address = endpoint_number; 442 uint8_t endpoint_address = endpoint_number;
440 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); 443 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size());
441 { 444 {
442 const std::vector<uint8_t>& storage = data.storage(); 445 const std::vector<uint8_t>& storage = data.storage();
443 std::copy(storage.begin(), storage.end(), buffer->data()); 446 std::copy(storage.begin(), storage.end(), buffer->data());
444 } 447 }
445 device_handle_->IsochronousTransferOut( 448 device_handle_->IsochronousTransferOut(
446 endpoint_address, buffer, packet_lengths.storage(), timeout, 449 endpoint_address, buffer, packet_lengths.storage(), timeout,
447 base::Bind(&OnIsochronousTransferOut, base::Passed(&callback_ptr))); 450 base::Bind(&OnIsochronousTransferOut, base::Passed(&callback_ptr)));
448 } 451 }
449 452
450 void DeviceImpl::OnDeviceRemoved(scoped_refptr<UsbDevice> device) { 453 void DeviceImpl::OnDeviceRemoved(scoped_refptr<UsbDevice> device) {
451 DCHECK_EQ(device_, device); 454 DCHECK_EQ(device_, device);
452 delete this; 455 delete this;
453 } 456 }
454 457
455 } // namespace usb 458 } // namespace usb
456 } // namespace device 459 } // namespace device
OLDNEW
« no previous file with comments | « device/udev_linux/udev_loader.cc ('k') | device/usb/mojo/device_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698