Index: device/devices_app/usb/device_impl.cc |
diff --git a/device/devices_app/usb/device_impl.cc b/device/devices_app/usb/device_impl.cc |
deleted file mode 100644 |
index 2eb3ed5d461c5647981e5741fa962f3f3a151f39..0000000000000000000000000000000000000000 |
--- a/device/devices_app/usb/device_impl.cc |
+++ /dev/null |
@@ -1,464 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "device/devices_app/usb/device_impl.h" |
- |
-#include <stddef.h> |
- |
-#include <algorithm> |
-#include <numeric> |
-#include <utility> |
-#include <vector> |
- |
-#include "base/bind.h" |
-#include "base/callback.h" |
-#include "base/stl_util.h" |
-#include "device/devices_app/usb/type_converters.h" |
-#include "device/usb/usb_descriptors.h" |
-#include "device/usb/usb_device.h" |
-#include "net/base/io_buffer.h" |
- |
-namespace device { |
-namespace usb { |
- |
-namespace { |
- |
-using MojoTransferInCallback = |
- mojo::Callback<void(TransferStatus, mojo::Array<uint8_t>)>; |
- |
-using MojoTransferOutCallback = mojo::Callback<void(TransferStatus)>; |
- |
-template <typename... Args> |
-void CallMojoCallback(scoped_ptr<mojo::Callback<void(Args...)>> callback, |
- Args... args) { |
- callback->Run(args...); |
-} |
- |
-// Generic wrapper to convert a Mojo callback to something we can rebind and |
-// pass around. This is only usable for callbacks with no move-only arguments. |
-template <typename... Args> |
-base::Callback<void(Args...)> WrapMojoCallback( |
- const mojo::Callback<void(Args...)>& callback) { |
- // mojo::Callback is not thread safe. By wrapping |callback| in a scoped_ptr |
- // we guarantee that it will be freed when CallMojoCallback is run and not |
- // retained until the base::Callback is destroyed, which could happen on any |
- // thread. This pattern is also used below in places where this generic |
- // wrapper is not used. |
- auto callback_ptr = |
- make_scoped_ptr(new mojo::Callback<void(Args...)>(callback)); |
- return base::Bind(&CallMojoCallback<Args...>, base::Passed(&callback_ptr)); |
-} |
- |
-void OnPermissionCheckComplete( |
- const base::Callback<void(bool)>& callback, |
- const base::Callback<void(const base::Callback<void(bool)>&)>& action, |
- bool allowed) { |
- if (allowed) |
- action.Run(callback); |
- else |
- callback.Run(false); |
-} |
- |
-scoped_refptr<net::IOBuffer> CreateTransferBuffer(size_t size) { |
- scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer( |
- std::max(static_cast<size_t>(1u), static_cast<size_t>(size))); |
- return buffer; |
-} |
- |
-void OnTransferIn(scoped_ptr<MojoTransferInCallback> callback, |
- UsbTransferStatus status, |
- scoped_refptr<net::IOBuffer> buffer, |
- size_t buffer_size) { |
- mojo::Array<uint8_t> data; |
- if (buffer) { |
- // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a |
- // std::vector<uint8_t> instead of net::IOBuffer. Then we could move |
- // instead of copy. |
- std::vector<uint8_t> bytes(buffer_size); |
- std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin()); |
- data.Swap(&bytes); |
- } |
- callback->Run(mojo::ConvertTo<TransferStatus>(status), std::move(data)); |
-} |
- |
-void OnControlTransferInPermissionCheckComplete( |
- scoped_refptr<UsbDeviceHandle> device_handle, |
- ControlTransferParamsPtr params, |
- int length, |
- int timeout, |
- scoped_ptr<Device::ControlTransferInCallback> callback, |
- bool allowed) { |
- if (allowed) { |
- scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); |
- device_handle->ControlTransfer( |
- USB_DIRECTION_INBOUND, |
- mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), |
- mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), |
- params->request, params->value, params->index, buffer, length, timeout, |
- base::Bind(&OnTransferIn, base::Passed(&callback))); |
- } else { |
- mojo::Array<uint8_t> data; |
- callback->Run(TransferStatus::PERMISSION_DENIED, std::move(data)); |
- } |
-} |
- |
-void OnTransferOut(scoped_ptr<MojoTransferOutCallback> callback, |
- UsbTransferStatus status, |
- scoped_refptr<net::IOBuffer> buffer, |
- size_t buffer_size) { |
- callback->Run(mojo::ConvertTo<TransferStatus>(status)); |
-} |
- |
-void OnControlTransferOutPermissionCheckComplete( |
- scoped_refptr<UsbDeviceHandle> device_handle, |
- ControlTransferParamsPtr params, |
- mojo::Array<uint8_t> data, |
- int timeout, |
- scoped_ptr<Device::ControlTransferOutCallback> callback, |
- bool allowed) { |
- if (allowed) { |
- scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); |
- const std::vector<uint8_t>& storage = data.storage(); |
- std::copy(storage.begin(), storage.end(), buffer->data()); |
- device_handle->ControlTransfer( |
- USB_DIRECTION_OUTBOUND, |
- mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), |
- mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), |
- params->request, params->value, params->index, buffer, data.size(), |
- timeout, base::Bind(&OnTransferOut, base::Passed(&callback))); |
- } else { |
- callback->Run(TransferStatus::PERMISSION_DENIED); |
- } |
-} |
- |
-mojo::Array<IsochronousPacketPtr> BuildIsochronousPacketArray( |
- mojo::Array<uint32_t> packet_lengths, |
- TransferStatus status) { |
- mojo::Array<IsochronousPacketPtr> packets(packet_lengths.size()); |
- for (size_t i = 0; i < packet_lengths.size(); ++i) { |
- packets[i] = IsochronousPacket::New(); |
- packets[i]->length = packet_lengths[i]; |
- packets[i]->status = status; |
- } |
- return packets; |
-} |
- |
-void OnIsochronousTransferIn( |
- scoped_ptr<Device::IsochronousTransferInCallback> callback, |
- scoped_refptr<net::IOBuffer> buffer, |
- const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { |
- mojo::Array<uint8_t> data; |
- if (buffer) { |
- // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a |
- // std::vector<uint8_t> instead of net::IOBuffer. Then we could move |
- // instead of copy. |
- uint32_t buffer_size = |
- std::accumulate(packets.begin(), packets.end(), 0u, |
- [](const uint32_t& a, |
- const UsbDeviceHandle::IsochronousPacket& packet) { |
- return a + packet.length; |
- }); |
- std::vector<uint8_t> bytes(buffer_size); |
- std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin()); |
- data.Swap(&bytes); |
- } |
- callback->Run(std::move(data), |
- mojo::Array<IsochronousPacketPtr>::From(packets)); |
-} |
- |
-void OnIsochronousTransferOut( |
- scoped_ptr<Device::IsochronousTransferOutCallback> callback, |
- scoped_refptr<net::IOBuffer> buffer, |
- const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { |
- callback->Run(mojo::Array<IsochronousPacketPtr>::From(packets)); |
-} |
- |
-} // namespace |
- |
-DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device, |
- PermissionProviderPtr permission_provider, |
- mojo::InterfaceRequest<Device> request) |
- : binding_(this, std::move(request)), |
- device_(device), |
- permission_provider_(std::move(permission_provider)), |
- weak_factory_(this) { |
- // This object owns itself and will be destroyed if either the message pipe |
- // it is bound to is closed or the PermissionProvider it depends on is |
- // unavailable. |
- binding_.set_connection_error_handler([this]() { delete this; }); |
- permission_provider_.set_connection_error_handler([this]() { delete this; }); |
-} |
- |
-DeviceImpl::~DeviceImpl() { |
- CloseHandle(); |
-} |
- |
-void DeviceImpl::CloseHandle() { |
- if (device_handle_) |
- device_handle_->Close(); |
- device_handle_ = nullptr; |
-} |
- |
-void DeviceImpl::HasControlTransferPermission( |
- ControlTransferRecipient recipient, |
- uint16_t index, |
- const base::Callback<void(bool)>& callback) { |
- DCHECK(device_handle_); |
- const UsbConfigDescriptor* config = device_->GetActiveConfiguration(); |
- |
- if (recipient == ControlTransferRecipient::INTERFACE || |
- recipient == ControlTransferRecipient::ENDPOINT) { |
- if (!config) { |
- callback.Run(false); |
- return; |
- } |
- |
- uint8_t interface_number = index & 0xff; |
- if (recipient == ControlTransferRecipient::ENDPOINT) { |
- if (!device_handle_->FindInterfaceByEndpoint(index & 0xff, |
- &interface_number)) { |
- callback.Run(false); |
- return; |
- } |
- } |
- |
- permission_provider_->HasInterfacePermission( |
- interface_number, config->configuration_value, |
- DeviceInfo::From(*device_), callback); |
- } else if (config) { |
- permission_provider_->HasConfigurationPermission( |
- config->configuration_value, DeviceInfo::From(*device_), callback); |
- } else { |
- // Client must already have device permission to have gotten this far. |
- callback.Run(true); |
- } |
-} |
- |
-void DeviceImpl::OnOpen(const OpenCallback& callback, |
- scoped_refptr<UsbDeviceHandle> handle) { |
- device_handle_ = handle; |
- callback.Run(handle ? OpenDeviceError::OK : OpenDeviceError::ACCESS_DENIED); |
-} |
- |
-void DeviceImpl::GetDeviceInfo(const GetDeviceInfoCallback& callback) { |
- callback.Run(DeviceInfo::From(*device_)); |
-} |
- |
-void DeviceImpl::GetConfiguration(const GetConfigurationCallback& callback) { |
- const UsbConfigDescriptor* config = device_->GetActiveConfiguration(); |
- callback.Run(config ? config->configuration_value : 0); |
-} |
- |
-void DeviceImpl::Open(const OpenCallback& callback) { |
- device_->Open( |
- base::Bind(&DeviceImpl::OnOpen, weak_factory_.GetWeakPtr(), callback)); |
-} |
- |
-void DeviceImpl::Close(const CloseCallback& callback) { |
- CloseHandle(); |
- callback.Run(); |
-} |
- |
-void DeviceImpl::SetConfiguration(uint8_t value, |
- const SetConfigurationCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(false); |
- return; |
- } |
- |
- auto set_configuration = |
- base::Bind(&UsbDeviceHandle::SetConfiguration, device_handle_, value); |
- permission_provider_->HasConfigurationPermission( |
- value, DeviceInfo::From(*device_), |
- base::Bind(&OnPermissionCheckComplete, WrapMojoCallback(callback), |
- set_configuration)); |
-} |
- |
-void DeviceImpl::ClaimInterface(uint8_t interface_number, |
- const ClaimInterfaceCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(false); |
- return; |
- } |
- |
- const UsbConfigDescriptor* config = device_->GetActiveConfiguration(); |
- if (!config) { |
- callback.Run(false); |
- return; |
- } |
- |
- auto claim_interface = base::Bind(&UsbDeviceHandle::ClaimInterface, |
- device_handle_, interface_number); |
- permission_provider_->HasInterfacePermission( |
- interface_number, config->configuration_value, DeviceInfo::From(*device_), |
- base::Bind(&OnPermissionCheckComplete, WrapMojoCallback(callback), |
- claim_interface)); |
-} |
- |
-void DeviceImpl::ReleaseInterface(uint8_t interface_number, |
- const ReleaseInterfaceCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(false); |
- return; |
- } |
- |
- device_handle_->ReleaseInterface(interface_number, |
- WrapMojoCallback(callback)); |
-} |
- |
-void DeviceImpl::SetInterfaceAlternateSetting( |
- uint8_t interface_number, |
- uint8_t alternate_setting, |
- const SetInterfaceAlternateSettingCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(false); |
- return; |
- } |
- |
- device_handle_->SetInterfaceAlternateSetting( |
- interface_number, alternate_setting, WrapMojoCallback(callback)); |
-} |
- |
-void DeviceImpl::Reset(const ResetCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(false); |
- return; |
- } |
- |
- device_handle_->ResetDevice(WrapMojoCallback(callback)); |
-} |
- |
-void DeviceImpl::ClearHalt(uint8_t endpoint, |
- const ClearHaltCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(false); |
- return; |
- } |
- |
- device_handle_->ClearHalt(endpoint, WrapMojoCallback(callback)); |
-} |
- |
-void DeviceImpl::ControlTransferIn(ControlTransferParamsPtr params, |
- uint32_t length, |
- uint32_t timeout, |
- const ControlTransferInCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(TransferStatus::TRANSFER_ERROR, mojo::Array<uint8_t>()); |
- return; |
- } |
- |
- auto callback_ptr = make_scoped_ptr(new ControlTransferInCallback(callback)); |
- ControlTransferRecipient recipient = params->recipient; |
- uint16_t index = params->index; |
- HasControlTransferPermission( |
- recipient, index, |
- base::Bind(&OnControlTransferInPermissionCheckComplete, device_handle_, |
- base::Passed(¶ms), length, timeout, |
- base::Passed(&callback_ptr))); |
-} |
- |
-void DeviceImpl::ControlTransferOut( |
- ControlTransferParamsPtr params, |
- mojo::Array<uint8_t> data, |
- uint32_t timeout, |
- const ControlTransferOutCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(TransferStatus::TRANSFER_ERROR); |
- return; |
- } |
- |
- auto callback_ptr = make_scoped_ptr(new ControlTransferOutCallback(callback)); |
- ControlTransferRecipient recipient = params->recipient; |
- uint16_t index = params->index; |
- HasControlTransferPermission( |
- recipient, index, |
- base::Bind(&OnControlTransferOutPermissionCheckComplete, device_handle_, |
- base::Passed(¶ms), base::Passed(&data), timeout, |
- base::Passed(&callback_ptr))); |
-} |
- |
-void DeviceImpl::GenericTransferIn(uint8_t endpoint_number, |
- uint32_t length, |
- uint32_t timeout, |
- const GenericTransferInCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(TransferStatus::TRANSFER_ERROR, mojo::Array<uint8_t>()); |
- return; |
- } |
- |
- auto callback_ptr = make_scoped_ptr(new GenericTransferInCallback(callback)); |
- uint8_t endpoint_address = endpoint_number | 0x80; |
- scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); |
- device_handle_->GenericTransfer( |
- USB_DIRECTION_INBOUND, endpoint_address, buffer, length, timeout, |
- base::Bind(&OnTransferIn, base::Passed(&callback_ptr))); |
-} |
- |
-void DeviceImpl::GenericTransferOut( |
- uint8_t endpoint_number, |
- mojo::Array<uint8_t> data, |
- uint32_t timeout, |
- const GenericTransferOutCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(TransferStatus::TRANSFER_ERROR); |
- return; |
- } |
- |
- auto callback_ptr = make_scoped_ptr(new GenericTransferOutCallback(callback)); |
- uint8_t endpoint_address = endpoint_number; |
- scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); |
- const std::vector<uint8_t>& storage = data.storage(); |
- std::copy(storage.begin(), storage.end(), buffer->data()); |
- device_handle_->GenericTransfer( |
- USB_DIRECTION_OUTBOUND, endpoint_address, buffer, data.size(), timeout, |
- base::Bind(&OnTransferOut, base::Passed(&callback_ptr))); |
-} |
- |
-void DeviceImpl::IsochronousTransferIn( |
- uint8_t endpoint_number, |
- mojo::Array<uint32_t> packet_lengths, |
- uint32_t timeout, |
- const IsochronousTransferInCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(mojo::Array<uint8_t>(), |
- BuildIsochronousPacketArray(std::move(packet_lengths), |
- TransferStatus::TRANSFER_ERROR)); |
- return; |
- } |
- |
- auto callback_ptr = |
- make_scoped_ptr(new IsochronousTransferInCallback(callback)); |
- uint8_t endpoint_address = endpoint_number | 0x80; |
- device_handle_->IsochronousTransferIn( |
- endpoint_address, packet_lengths.storage(), timeout, |
- base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr))); |
-} |
- |
-void DeviceImpl::IsochronousTransferOut( |
- uint8_t endpoint_number, |
- mojo::Array<uint8_t> data, |
- mojo::Array<uint32_t> packet_lengths, |
- uint32_t timeout, |
- const IsochronousTransferOutCallback& callback) { |
- if (!device_handle_) { |
- callback.Run(BuildIsochronousPacketArray(std::move(packet_lengths), |
- TransferStatus::TRANSFER_ERROR)); |
- return; |
- } |
- |
- auto callback_ptr = |
- make_scoped_ptr(new IsochronousTransferOutCallback(callback)); |
- uint8_t endpoint_address = endpoint_number; |
- scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); |
- { |
- const std::vector<uint8_t>& storage = data.storage(); |
- std::copy(storage.begin(), storage.end(), buffer->data()); |
- } |
- device_handle_->IsochronousTransferOut( |
- endpoint_address, buffer, packet_lengths.storage(), timeout, |
- base::Bind(&OnIsochronousTransferOut, base::Passed(&callback_ptr))); |
-} |
- |
-} // namespace usb |
-} // namespace device |