Commit 5a116a27 authored by Richard Machado's avatar Richard Machado Committed by Commit Bot

Impl. UsbDeviceHandleMac

I implemented all virtual methods of UsbDeviceHandle, which includes all
the types of transfer methods. I also implemented various helper methods
to assist with the mac implementation of UsbDeviceHandle.

Bug: 1096743
Change-Id: I8f2d0edeb818ef7e80805e51edd3b32e8e038d08
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2300638
Commit-Queue: Ricky Machado <richardmachado@google.com>
Reviewed-by: default avatarMatt Reynolds <mattreynolds@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarOvidio de Jesús Ruiz-Henríquez <odejesush@chromium.org>
Cr-Commit-Position: refs/heads/master@{#796613}
parent 3ca55e54
......@@ -12,22 +12,36 @@
#include <IOKit/IOReturn.h>
#include <IOKit/usb/IOUSBLib.h>
#include <memory>
#include <vector>
#include "base/containers/flat_set.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_ioplugininterface.h"
#include "base/memory/ref_counted.h"
#include "services/device/public/mojom/usb_device.mojom.h"
namespace base {
class RefCountedBytes;
}
namespace device {
class UsbDeviceMac;
struct Transfer;
class UsbDeviceHandleMac : public UsbDeviceHandle {
public:
UsbDeviceHandleMac(const UsbDeviceHandleMac&) = delete;
UsbDeviceHandleMac& operator=(const UsbDeviceHandleMac&) = delete;
using ScopedIOUSBDeviceInterface =
base::mac::ScopedIOPluginInterface<IOUSBDeviceInterface182>;
using ScopedIOUSBInterfaceInterface =
base::mac::ScopedIOPluginInterface<IOUSBInterfaceInterface182>;
// UsbDeviceHandle implementation:
UsbDeviceHandleMac(scoped_refptr<UsbDeviceMac> device,
ScopedIOUSBDeviceInterface device_interface);
UsbDeviceHandleMac(const UsbDeviceHandleMac&) = delete;
UsbDeviceHandleMac& operator=(const UsbDeviceHandleMac&) = delete;
scoped_refptr<UsbDevice> GetDevice() const override;
void Close() override;
void SetConfiguration(int configuration_value,
......@@ -67,17 +81,64 @@ class UsbDeviceHandleMac : public UsbDeviceHandle {
const mojom::UsbInterfaceInfo* FindInterfaceByEndpoint(
uint8_t endpoint_address) override;
UsbDeviceHandleMac(scoped_refptr<UsbDeviceMac> device,
base::mac::ScopedIOPluginInterface<IOUSBDeviceInterface182>
device_interface);
protected:
~UsbDeviceHandleMac() override;
friend class UsbDeviceMac;
private:
base::mac::ScopedIOPluginInterface<IOUSBDeviceInterface182> device_interface_;
struct EndpointMapValue {
const mojom::UsbInterfaceInfo* interface;
const mojom::UsbEndpointInfo* endpoint;
uint8_t pipe_reference;
};
void BulkIn(const ScopedIOUSBInterfaceInterface& interface_interface,
uint8_t pipe_reference,
scoped_refptr<base::RefCountedBytes> buffer,
uint32_t timeout,
std::unique_ptr<Transfer> transfer);
void BulkOut(const ScopedIOUSBInterfaceInterface& interface_interface,
uint8_t pipe_reference,
scoped_refptr<base::RefCountedBytes> buffer,
uint32_t timeout,
std::unique_ptr<Transfer> transfer);
void InterruptIn(const ScopedIOUSBInterfaceInterface& interface_interface,
uint8_t pipe_reference,
scoped_refptr<base::RefCountedBytes> buffer,
std::unique_ptr<Transfer> transfer);
void InterruptOut(const ScopedIOUSBInterfaceInterface& interface_interface,
uint8_t pipe_reference,
scoped_refptr<base::RefCountedBytes> buffer,
std::unique_ptr<Transfer> transfer);
// Refresh endpoint_map_ after ClaimInterface, ReleaseInterface and
// SetInterfaceAlternateSetting. It is needed so that endpoints can be mapped
// to their respective mojom Interface.
void RefreshEndpointMap();
void ReportIsochronousTransferError(
UsbDeviceHandle::IsochronousTransferCallback callback,
std::vector<uint32_t> packet_lengths,
mojom::UsbTransferStatus status);
void Clear();
void OnAsyncGeneric(IOReturn result, size_t size, Transfer* transfer);
void OnAsyncIsochronous(IOReturn result, size_t size, Transfer* transfer);
static void AsyncIoCallback(void* refcon, IOReturn result, void* arg0);
// A map from the endpoint indices to its corresponding EndpointMapValue,
// which contains the Interface and Endpoint Mojo structures.
using EndpointMap = base::flat_map<int, EndpointMapValue>;
EndpointMap endpoint_map_;
base::flat_set<std::unique_ptr<Transfer>, base::UniquePtrComparator>
transfers_;
ScopedIOUSBDeviceInterface device_interface_;
scoped_refptr<UsbDeviceMac> device_;
// Both maps take the interface number in as the respective key.
base::flat_map<uint8_t, ScopedIOUSBInterfaceInterface> interfaces_;
base::flat_map<uint8_t, base::ScopedCFTypeRef<CFRunLoopSourceRef>> sources_;
};
} // namespace device
......
......@@ -36,7 +36,6 @@ void UsbDeviceMac::Open(OpenCallback callback) {
std::move(callback).Run(nullptr);
return;
}
// IOServiceGetMatchingService consumes a reference to the matching dictionary
// passed to it.
base::mac::ScopedIOObject<io_service_t> usb_device(
......@@ -60,13 +59,12 @@ void UsbDeviceMac::Open(OpenCallback callback) {
}
base::mac::ScopedIOPluginInterface<IOUSBDeviceInterface182> device_interface;
IOReturn result =
(*plugin_interface)
->QueryInterface(
plugin_interface.get(),
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
reinterpret_cast<LPVOID*>(device_interface.InitializeInto()));
if (result || !device_interface) {
kr = (*plugin_interface)
->QueryInterface(
plugin_interface.get(),
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
reinterpret_cast<LPVOID*>(device_interface.InitializeInto()));
if (kr != kIOReturnSuccess || !device_interface) {
USB_LOG(ERROR) << "Couldn’t create a device interface.";
std::move(callback).Run(nullptr);
return;
......@@ -83,8 +81,7 @@ void UsbDeviceMac::Open(OpenCallback callback) {
this, std::move(device_interface));
handles().push_back(device_handle.get());
std::move(callback).Run(nullptr);
std::move(callback).Run(device_handle);
}
} // namespace device
......@@ -149,8 +149,9 @@ void UsbServiceLinux::BlockingTaskRunnerHelper::OnDeviceAdded(
return;
std::unique_ptr<UsbDeviceDescriptor> descriptor(new UsbDeviceDescriptor());
if (!descriptor->Parse(std::vector<uint8_t>(descriptors_str.begin(),
descriptors_str.end()))) {
if (!descriptor->Parse(base::make_span(
reinterpret_cast<const uint8_t*>(descriptors_str.data()),
descriptors_str.size()))) {
return;
}
......
......@@ -158,14 +158,13 @@ void UsbServiceMac::AddDevice(io_service_t device) {
}
base::mac::ScopedIOPluginInterface<IOUSBDeviceInterface182> device_interface;
IOReturn result =
(*plugin_interface)
->QueryInterface(
plugin_interface.get(),
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
reinterpret_cast<LPVOID*>(device_interface.InitializeInto()));
if (result || !device_interface) {
kr = (*plugin_interface)
->QueryInterface(
plugin_interface.get(),
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
reinterpret_cast<LPVOID*>(device_interface.InitializeInto()));
if (kr != kIOReturnSuccess || !device_interface) {
USB_LOG(ERROR) << "Couldn’t create a device interface.";
return;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment