123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- // Copyright 2020 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 "services/device/usb/usb_device_mac.h"
- #include <IOKit/IOCFPlugIn.h>
- #include <IOKit/IOKitLib.h>
- #include <IOKit/IOReturn.h>
- #include <IOKit/usb/IOUSBLib.h>
- #include <utility>
- #include "base/mac/foundation_util.h"
- #include "base/mac/scoped_ionotificationportref.h"
- #include "base/mac/scoped_ioobject.h"
- #include "base/mac/scoped_ioplugininterface.h"
- #include "components/device_event_log/device_event_log.h"
- #include "services/device/usb/usb_descriptors.h"
- #include "services/device/usb/usb_device_handle.h"
- #include "services/device/usb/usb_device_handle_mac.h"
- namespace device {
- UsbDeviceMac::UsbDeviceMac(uint64_t entry_id,
- mojom::UsbDeviceInfoPtr device_info)
- : UsbDevice(std::move(device_info)), entry_id_(entry_id) {}
- UsbDeviceMac::~UsbDeviceMac() = default;
- void UsbDeviceMac::Open(OpenCallback callback) {
- base::ScopedCFTypeRef<CFDictionaryRef> matching_dict(
- IORegistryEntryIDMatching(entry_id()));
- if (!matching_dict.get()) {
- USB_LOG(ERROR) << "Failed to create matching dictionary for ID.";
- 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(
- IOServiceGetMatchingService(kIOMasterPortDefault,
- matching_dict.release()));
- if (!usb_device.get()) {
- USB_LOG(ERROR) << "IOService not found for ID.";
- std::move(callback).Run(nullptr);
- return;
- }
- base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> plugin_interface;
- int32_t score;
- IOReturn kr = IOCreatePlugInInterfaceForService(
- usb_device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID,
- plugin_interface.InitializeInto(), &score);
- if ((kr != kIOReturnSuccess) || !plugin_interface) {
- USB_LOG(ERROR) << "Unable to create a plug-in: " << std::hex << kr;
- std::move(callback).Run(nullptr);
- return;
- }
- base::mac::ScopedIOPluginInterface<IOUSBDeviceInterface187> 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;
- }
- kr = (*device_interface)->USBDeviceOpen(device_interface);
- if (kr != kIOReturnSuccess) {
- USB_LOG(ERROR) << "Failed to open device: " << std::hex << kr;
- std::move(callback).Run(nullptr);
- return;
- }
- auto device_handle = base::MakeRefCounted<UsbDeviceHandleMac>(
- this, std::move(device_interface));
- handles().push_back(device_handle.get());
- std::move(callback).Run(device_handle);
- }
- } // namespace device
|