/// <summary>
 /// Creates a <see cref="IDeviceFactory"/> for UWP Hid devices
 /// </summary>
 /// <param name="filterDeviceDefinition">Devices must match this</param>
 /// <param name="loggerFactory"><see href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.iloggerfactory"/></param>
 /// <param name="classGuid">Filters by specified class guid</param>
 /// <param name="deviceInformationFilter"></param>
 /// <param name="dataReceiver"></param>
 /// <param name="readBufferSize">Override the input report size</param>
 /// <param name="readTransferTransform">Exposes the raw data from the device (including Report Id) on reads and allows you to format the returned <see cref="TransferResult"/></param>
 /// <param name="writeTransferTransform">Given the Report Id and data supplied for the write, allow you to format the raw data that is sent to the device</param>
 /// <param name="writeReportTransform">Given the data supplied, allow you to divide the data in to a <see cref="Report"/></param>
 /// <param name="writeBufferSize">Override the output report size</param>
 /// <param name="getConnectedDeviceDefinitionsAsync">Override the default call for getting definitions</param>
 /// <param name="getDevice"></param>
 /// <param name="readReportTransform">Allows you to manually convert the <see cref="Report"/> in to a <see cref="TransferResult"/> so that the Report Id is not discarded on ReadAsync. By default, this inserts the Report Id at index zero of the array.</param>
 /// <returns>A factory which enumerates and instantiates devices</returns>
 public static IDeviceFactory CreateUwpHidDeviceFactory(
     this FilterDeviceDefinition filterDeviceDefinition,
     ILoggerFactory loggerFactory = null,
     GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null,
     GetDeviceAsync getDevice = null,
     Guid?classGuid           = null,
     Func <wde.DeviceInformation, bool> deviceInformationFilter = null,
     IDataReceiver dataReceiver = null,
     ushort?writeBufferSize     = null,
     ushort?readBufferSize      = null,
     Func <Report, TransferResult> readReportTransform   = null,
     Func <TransferResult, Report> readTransferTransform = null,
     Func <byte[], byte, byte[]> writeTransferTransform  = null,
     WriteReportTransform writeReportTransform           = null) => CreateUwpHidDeviceFactory(
     new List <FilterDeviceDefinition> {
     filterDeviceDefinition
 },
     loggerFactory,
     getConnectedDeviceDefinitionsAsync,
     getDevice,
     classGuid,
     deviceInformationFilter,
     dataReceiver,
     writeBufferSize,
     readBufferSize,
     readReportTransform,
     readTransferTransform,
     writeTransferTransform,
     writeReportTransform);
 public static IDeviceFactory CreateAndroidUsbDeviceFactory(
     this FilterDeviceDefinition filterDeviceDefinition,
     UsbManager usbManager,
     Context context,
     ILoggerFactory loggerFactory = null,
     GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null,
     GetUsbInterfaceManager getUsbInterfaceManager = null,
     ushort?readBufferSize          = null,
     ushort?writeBufferSize         = null,
     IAndroidFactory androidFactory = null,
     Func <AndroidUsbDevice, IUsbPermissionBroadcastReceiver> getUsbPermissionBroadcastReceiver = null
     ) =>
 CreateAndroidUsbDeviceFactory(
     new ReadOnlyCollection <FilterDeviceDefinition>(new List <FilterDeviceDefinition> {
     filterDeviceDefinition
 }),
     usbManager,
     context,
     loggerFactory,
     getConnectedDeviceDefinitionsAsync,
     getUsbInterfaceManager,
     readBufferSize,
     writeBufferSize,
     androidFactory,
     getUsbPermissionBroadcastReceiver);
 /// <summary>
 /// Creates a <see cref="IDeviceFactory"/> for Windows Hid devices
 /// </summary>
 /// <param name="filterDeviceDefinition">Devices must match this</param>
 /// <param name="loggerFactory"><see href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.iloggerfactory"/></param>
 /// <param name="hidApiService">Abstraction for Hid interaction</param>
 /// <param name="classGuid">Filters by specified class guid</param>
 /// <param name="readBufferSize">Override the input report size</param>
 /// <param name="writeBufferSize">Override the output report size</param>
 /// <param name="writeReportTransform">Given the data supplied, allow you to divide the data in to a <see cref="Report"/></param>
 /// <param name="getConnectedDeviceDefinitionsAsync">Override the default call for getting definitions</param>
 /// <param name="readReportTransform">Allows you to manually convert the <see cref="Report"/> in to a <see cref="TransferResult"/> so that the Report Id is not discarded on ReadAsync. By default, this inserts the Report Id at index zero of the array.</param>
 /// <param name="readTransferTransform">Exposes the raw data from the device (including Report Id) on reads and allows you to format the returned <see cref="TransferResult"/></param>
 /// <param name="writeTransferTransform">Given the Report Id and data supplied for the write, allow you to format the raw data that is sent to the device</param>
 /// <returns>A factory which enumerates and instantiates devices</returns>
 public static IDeviceFactory CreateWindowsHidDeviceFactory(
     this FilterDeviceDefinition filterDeviceDefinition,
     ILoggerFactory loggerFactory = null,
     IHidApiService hidApiService = null,
     Guid?classGuid         = null,
     ushort?readBufferSize  = null,
     ushort?writeBufferSize = null,
     GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null,
     Func <Report, TransferResult> readReportTransform   = null,
     Func <TransferResult, Report> readTransferTransform = null,
     Func <byte[], byte, byte[]> writeTransferTransform  = null,
     WriteReportTransform writeReportTransform           = null)
 {
     return(CreateWindowsHidDeviceFactory(
                new ReadOnlyCollection <FilterDeviceDefinition>(new List <FilterDeviceDefinition> {
         filterDeviceDefinition
     }),
                loggerFactory,
                hidApiService,
                classGuid,
                readBufferSize,
                writeBufferSize,
                getConnectedDeviceDefinitionsAsync,
                readReportTransform,
                readTransferTransform,
                writeTransferTransform,
                writeReportTransform));
 }
        /// <summary>
        /// Creates a factory Hid devices
        /// </summary>
        /// <param name="filterDeviceDefinitions">Devices must match these</param>
        /// <param name="loggerFactory"><see href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.iloggerfactory"/></param>
        /// <param name="hidApiService">Abstraction for Hid interaction</param>
        /// <param name="classGuid">Filters by specified class guid</param>
        /// <param name="readBufferSize">Override the input report size</param>
        /// <param name="writeBufferSize">Override the output report size</param>
        /// <param name="getConnectedDeviceDefinitionsAsync">Override the default call for getting definitions</param>
        /// <param name="readReportTransform">Allows you to manually convert the <see cref="Report"/> in to a <see cref="TransferResult"/> so that the Report Id is not discarded on ReadAsync. By default, this inserts the Report Id at index zero of the array.</param>
        /// <param name="readTransferTransform">Exposes the raw data from the device (including Report Id) on reads and allows you to format the returned <see cref="TransferResult"/></param>
        /// <param name="writeTransferTransform">Given the Report Id and data supplied for the write, allow you to format the raw data that is sent to the device</param>
        /// <param name="writeReportTransform">Given the data supplied, allow you to divide the data in to a <see cref="Report"/></param>
        /// <returns>A factory which enumerates and instantiates devices</returns>
        public static IDeviceFactory CreateWindowsHidDeviceFactory(
            this IEnumerable <FilterDeviceDefinition> filterDeviceDefinitions,
            ILoggerFactory loggerFactory = null,
            IHidApiService hidApiService = null,
            Guid?classGuid         = null,
            ushort?readBufferSize  = null,
            ushort?writeBufferSize = null,
            GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null,
            Func <Report, TransferResult> readReportTransform   = null,
            Func <TransferResult, Report> readTransferTransform = null,
            Func <byte[], byte, byte[]> writeTransferTransform  = null,
            WriteReportTransform writeReportTransform           = null)
        {
            if (filterDeviceDefinitions == null)
            {
                throw new ArgumentNullException(nameof(filterDeviceDefinitions));
            }

            loggerFactory ??= NullLoggerFactory.Instance;

            var selectedHidApiService = hidApiService ?? new WindowsHidApiService(loggerFactory);

            classGuid ??= selectedHidApiService.GetHidGuid();

            if (getConnectedDeviceDefinitionsAsync == null)
            {
                var windowsDeviceEnumerator = new WindowsDeviceEnumerator(
                    loggerFactory.CreateLogger <WindowsDeviceEnumerator>(),
                    classGuid.Value,
                    (d, guid) => GetDeviceDefinition(d, selectedHidApiService, loggerFactory.CreateLogger(nameof(WindowsHidDeviceFactoryExtensions))),
                    c => Task.FromResult(!filterDeviceDefinitions.Any() || filterDeviceDefinitions.FirstOrDefault(f => f.IsDefinitionMatch(c, DeviceType.Hid)) != null)
                    );

                getConnectedDeviceDefinitionsAsync = windowsDeviceEnumerator.GetConnectedDeviceDefinitionsAsync;
            }

            return(new DeviceFactory(
                       loggerFactory,
                       getConnectedDeviceDefinitionsAsync,
                       (c, cancellationToken) => Task.FromResult <IDevice>(new HidDevice
                                                                           (
                                                                               new WindowsHidHandler(
                                                                                   c.DeviceId,
                                                                                   writeBufferSize,
                                                                                   readBufferSize,
                                                                                   hidApiService,
                                                                                   loggerFactory,
                                                                                   readTransferTransform,
                                                                                   writeTransferTransform),
                                                                               loggerFactory,
                                                                               readReportTransform,
                                                                               writeReportTransform
                                                                           )),
                       (c, cancellationToken) => Task.FromResult(c.DeviceType == DeviceType.Hid)));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Constructs a DeviceFactory
        /// </summary>
        /// <param name="loggerFactory">The factory for creating new loggers for each device</param>
        /// <param name="getConnectedDevicesAsync">A delegate that returns matching connected device definitions</param>
        /// <param name="getDevice">A delegate to construct the device based on the specified connected device definition</param>
        /// <param name="supportsDevice">A delegate that returns whether or not this factory supports the connected device</param>
        public DeviceFactory(

            ILoggerFactory loggerFactory,
            GetConnectedDeviceDefinitionsAsync getConnectedDevicesAsync,
            GetDeviceAsync getDevice,
            Func <ConnectedDeviceDefinition, CancellationToken, Task <bool> > supportsDevice
            )
        {
            _getConnectedDevicesAsync = getConnectedDevicesAsync ?? throw new ArgumentNullException(nameof(getConnectedDevicesAsync));
            _loggerFactory            = loggerFactory ?? NullLoggerFactory.Instance;
            _logger         = _loggerFactory.CreateLogger <DeviceFactory>();
            _getDevice      = getDevice;
            _supportsDevice = supportsDevice ?? throw new ArgumentNullException(nameof(supportsDevice));
        }
Ejemplo n.º 6
0
 public static IDeviceFactory CreateWindowsUsbDeviceFactory(
     ILoggerFactory loggerFactory = null,
     GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null,
     GetUsbInterfaceManager getUsbInterfaceManager = null,
     Guid?classGuid         = null,
     ushort?readBufferSize  = null,
     ushort?writeBufferSize = null
     ) => CreateWindowsUsbDeviceFactory(
     new List <FilterDeviceDefinition>(),
     loggerFactory,
     getConnectedDeviceDefinitionsAsync,
     getUsbInterfaceManager,
     classGuid,
     readBufferSize,
     writeBufferSize);
Ejemplo n.º 7
0
 public static IDeviceFactory CreateUwpUsbDeviceFactory(
     this FilterDeviceDefinition filterDeviceDefinitions,
     ILoggerFactory loggerFactory = null,
     GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null,
     GetUsbInterfaceManager getUsbInterfaceManager = null,
     ushort?readBufferSize  = null,
     ushort?writeBufferSize = null
     ) =>
 CreateUwpUsbDeviceFactory(
     new List <FilterDeviceDefinition> {
     filterDeviceDefinitions
 },
     loggerFactory,
     getConnectedDeviceDefinitionsAsync,
     getUsbInterfaceManager,
     readBufferSize,
     writeBufferSize);
 public static IDeviceFactory CreateUsbDeviceFactory(
     GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync,
     GetUsbInterfaceManager getUsbInterfaceManager,
     ILoggerFactory loggerFactory = null,
     Guid?classGuid = null)
 =>
 new DeviceFactory(
     loggerFactory,
     getConnectedDeviceDefinitionsAsync,
     async(d, cancellationToken) =>
 {
     var usbInterfaceManager = await getUsbInterfaceManager(d.DeviceId, cancellationToken).ConfigureAwait(false);
     return(new UsbDevice(d.DeviceId, usbInterfaceManager, loggerFactory));
 },
     //Support the device if the factory doesn't filter on class guid, or the filter matches the device
     (c, cancellationToken) => Task.FromResult(c.DeviceType == DeviceType.Usb && (classGuid == null || classGuid.Value == c.ClassGuid))
     );
Ejemplo n.º 9
0
        public static IDeviceFactory CreateUwpUsbDeviceFactory(
            this IEnumerable <FilterDeviceDefinition> filterDeviceDefinitions,
            ILoggerFactory loggerFactory,
            GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null,
            GetUsbInterfaceManager getUsbInterfaceManager = null,
            ushort?readBufferSize  = null,
            ushort?writeBufferSize = null,
            Func <wde.DeviceInformation, bool> deviceInformationFilter = null,
            Func <windowsUsbDevice, SetupPacket, byte[], CancellationToken, Task <TransferResult> > performControlTransferAsync = null,
            IDataReceiver dataReceiver = null)
        {
            if (getConnectedDeviceDefinitionsAsync == null)
            {
                //Filter to by device Id.
                //TODO: There is surely a better way to do this
                deviceInformationFilter ??= d =>
                d.Id.Contains(@"\\?\usb", StringComparison.OrdinalIgnoreCase) &&
                d.Id.Contains(@"vid", StringComparison.OrdinalIgnoreCase) &&
                d.Id.Contains(@"pid", StringComparison.OrdinalIgnoreCase);

                var uwpHidDeviceEnumerator = new UwpDeviceEnumerator(
                    AqsHelpers.GetAqs(filterDeviceDefinitions, DeviceType.Usb),
                    DeviceType.Usb,
                    (d, cancellationToken) => Task.FromResult(new ConnectionInfo {
                    CanConnect = true
                }),
                    loggerFactory,
                    deviceInformationFilter);

                getConnectedDeviceDefinitionsAsync = uwpHidDeviceEnumerator.GetConnectedDeviceDefinitionsAsync;
            }

            getUsbInterfaceManager ??= (deviceId, cancellationToken) =>
            Task.FromResult <IUsbInterfaceManager>(
                new UwpUsbInterfaceManager(
                    //TODO: no idea if this is OK...
                    new ConnectedDeviceDefinition(deviceId, DeviceType.Usb),
                    dataReceiver,
                    performControlTransferAsync,
                    loggerFactory,
                    readBufferSize,
                    writeBufferSize));

            return(UsbDeviceFactoryExtensions.CreateUsbDeviceFactory(getConnectedDeviceDefinitionsAsync, getUsbInterfaceManager, loggerFactory));
        }
Ejemplo n.º 10
0
        public static IDeviceFactory CreateWindowsUsbDeviceFactory(
            this IEnumerable <FilterDeviceDefinition> filterDeviceDefinitions,
            ILoggerFactory loggerFactory = null,
            GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null,
            GetUsbInterfaceManager getUsbInterfaceManager = null,
            Guid?classGuid         = null,
            ushort?readBufferSize  = null,
            ushort?writeBufferSize = null
            )
        {
            if (filterDeviceDefinitions == null)
            {
                throw new ArgumentNullException(nameof(filterDeviceDefinitions));
            }

            loggerFactory ??= NullLoggerFactory.Instance;

            if (getConnectedDeviceDefinitionsAsync == null)
            {
                var logger = loggerFactory.CreateLogger <WindowsDeviceEnumerator>();

                var uwpHidDeviceEnumerator = new WindowsDeviceEnumerator(
                    logger,
                    classGuid ?? WindowsDeviceConstants.WinUSBGuid,
                    (d, guid) => DeviceBase.GetDeviceDefinitionFromWindowsDeviceId(d, DeviceType.Usb, logger, guid),
                    c =>
                    Task.FromResult(!filterDeviceDefinitions.Any() || filterDeviceDefinitions.FirstOrDefault(f => f.IsDefinitionMatch(c, DeviceType.Usb)) != null));

                getConnectedDeviceDefinitionsAsync = uwpHidDeviceEnumerator.GetConnectedDeviceDefinitionsAsync;
            }

            getUsbInterfaceManager ??=
            (d, cancellationToken) =>
            Task.FromResult <IUsbInterfaceManager>(new WindowsUsbInterfaceManager
                                                   (
                                                       //TODO: no idea if this is OK...
                                                       d,
                                                       loggerFactory,
                                                       readBufferSize,
                                                       writeBufferSize
                                                   )
                                                   );

            return(UsbDeviceFactoryExtensions.CreateUsbDeviceFactory(getConnectedDeviceDefinitionsAsync, getUsbInterfaceManager, loggerFactory));
        }
        public static IDeviceFactory CreateAndroidUsbDeviceFactory(
            this IEnumerable <FilterDeviceDefinition> filterDeviceDefinitions,
            UsbManager usbManager,
            Context context,
            ILoggerFactory loggerFactory = null,
            GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null,
            GetUsbInterfaceManager getUsbInterfaceManager = null,
            ushort?readBufferSize          = null,
            ushort?writeBufferSize         = null,
            IAndroidFactory androidFactory = null,
            Func <AndroidUsbDevice, IUsbPermissionBroadcastReceiver> getUsbPermissionBroadcastReceiver = null
            )
        {
            if (usbManager == null)
            {
                throw new ArgumentNullException(nameof(usbManager));
            }
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            loggerFactory ??= NullLoggerFactory.Instance;

#if __ANDROID__
            androidFactory ??= new AndroidFactory();

            getUsbPermissionBroadcastReceiver ??= new Func <AndroidUsbDevice, IUsbPermissionBroadcastReceiver>((ud) =>
                                                                                                               new UsbPermissionBroadcastReceiver(
                                                                                                                   usbManager,
                                                                                                                   ud,
                                                                                                                   context,
                                                                                                                   androidFactory,
                                                                                                                   loggerFactory.CreateLogger <UsbPermissionBroadcastReceiver>()));
#else
            if (androidFactory == null)
            {
                throw new ArgumentNullException(nameof(androidFactory));
            }

            if (getUsbPermissionBroadcastReceiver == null)
            {
                throw new ArgumentNullException(nameof(getUsbPermissionBroadcastReceiver));
            }
#endif

            getConnectedDeviceDefinitionsAsync ??= (cancellationToken) =>
            {
                return(Task.FromResult <IEnumerable <ConnectedDeviceDefinition> >
                       (
                           new ReadOnlyCollection <ConnectedDeviceDefinition>
                           (
                               usbManager
                               .DeviceList
                               .Select(kvp => kvp.Value)
                               .Where
                               (
                                   d => filterDeviceDefinitions
                                   .FirstOrDefault
                                   (
                                       f =>
                                       (!f.VendorId.HasValue || f.VendorId.Value == d.VendorId) &&
                                       (!f.ProductId.HasValue || f.ProductId.Value == d.ProductId)
                                   ) != null
                               )
                               .Select(AndroidUsbInterfaceManager.GetAndroidDeviceDefinition)
                               .ToList()
                           )
                       ));
            };

            getUsbInterfaceManager ??= (a, cancellationToken) => Task.FromResult <IUsbInterfaceManager>(
                new AndroidUsbInterfaceManager(
                    usbManager,
                    //TODO: throw a validation message
                    int.Parse(a, IntParsingCulture),
                    androidFactory,
                    getUsbPermissionBroadcastReceiver,
                    loggerFactory,
                    readBufferSize,
                    writeBufferSize
                    ));

            return(UsbDeviceFactoryExtensions.CreateUsbDeviceFactory(getConnectedDeviceDefinitionsAsync, getUsbInterfaceManager, loggerFactory));
        }
        /// <summary>
        /// Creates a <see cref="IDeviceFactory"/> for UWP Hid devices
        /// </summary>
        /// <param name="filterDeviceDefinitions">Devices must match these</param>
        /// <param name="loggerFactory"><see href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.iloggerfactory"/></param>
        /// <param name="classGuid">Filters by specified class guid</param>
        /// <param name="deviceInformationFilter"></param>
        /// <param name="dataReceiver"></param>
        /// <param name="readBufferSize">Override the input report size</param>
        /// <param name="readTransferTransform">Exposes the raw data from the device (including Report Id) on reads and allows you to format the returned <see cref="TransferResult"/></param>
        /// <param name="writeTransferTransform">Given the Report Id and data supplied for the write, allow you to format the raw data that is sent to the device</param>
        /// <param name="writeReportTransform">Given the data supplied, allow you to divide the data in to a <see cref="Report"/></param>
        /// <param name="writeBufferSize">Override the output report size</param>
        /// <param name="getConnectedDeviceDefinitionsAsync">Override the default call for getting definitions</param>
        /// <param name="getDevice"></param>
        /// <param name="readReportTransform">Allows you to manually convert the <see cref="Report"/> in to a <see cref="TransferResult"/> so that the Report Id is not discarded on ReadAsync. By default, this inserts the Report Id at index zero of the array.</param>
        /// <returns>A factory which enumerates and instantiates devices</returns>
        public static IDeviceFactory CreateUwpHidDeviceFactory(
            this IEnumerable <FilterDeviceDefinition> filterDeviceDefinitions,
            ILoggerFactory loggerFactory = null,
            GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null,
            GetDeviceAsync getDevice = null,
            Guid?classGuid           = null,
            Func <wde.DeviceInformation, bool> deviceInformationFilter = null,
            IDataReceiver dataReceiver = null,
            ushort?writeBufferSize     = null,
            ushort?readBufferSize      = null,
            Func <Report, TransferResult> readReportTransform   = null,
            Func <TransferResult, Report> readTransferTransform = null,
            Func <byte[], byte, byte[]> writeTransferTransform  = null,
            WriteReportTransform writeReportTransform           = null)
        {
            loggerFactory ??= NullLoggerFactory.Instance;

            getDevice ??= (c, cancellationToken) => Task.FromResult <IDevice>(
                new HidDevice(
                    new UwpHidDeviceHandler(
                        c,
                        dataReceiver ??
                        new UwpDataReceiver(
                            new Observable <TransferResult>(),
                            loggerFactory.CreateLogger <UwpDataReceiver>()),
                        loggerFactory,
                        writeBufferSize,
                        readBufferSize,
                        readTransferTransform,
                        writeTransferTransform),
                    loggerFactory,
                    readReportTransform,
                    writeReportTransform));

            var aqs = AqsHelpers.GetAqs(filterDeviceDefinitions, DeviceType.Hid);

            var logger = loggerFactory.CreateLogger <UwpDeviceEnumerator>();

            if (getConnectedDeviceDefinitionsAsync == null)
            {
                //Filter to by device Id.
                //TODO: There is surely a better way to do this
                deviceInformationFilter ??= d =>
                d.Id.Contains(@"\\?\hid", StringComparison.OrdinalIgnoreCase) &&
                d.Id.Contains(@"vid", StringComparison.OrdinalIgnoreCase) &&
                d.Id.Contains(@"pid", StringComparison.OrdinalIgnoreCase);

                var uwpHidDeviceEnumerator = new UwpDeviceEnumerator(
                    aqs,
                    DeviceType.Hid,
                    async(deviceId, cancellationToken) =>
                {
                    using var hidDevice = await UwpHidDeviceHandler.GetHidDevice(deviceId).AsTask(cancellationToken);

                    var canConnect = hidDevice != null;

                    if (!canConnect)
                    {
                        return new ConnectionInfo {
                            CanConnect = false
                        }
                    }
                    ;

                    logger?.LogInformation("Testing device connection. Id: {deviceId}. Can connect: {canConnect}", deviceId, true);

                    return(new ConnectionInfo {
                        CanConnect = true, UsagePage = hidDevice.UsagePage
                    });
                },
                    loggerFactory,
                    deviceInformationFilter);

                getConnectedDeviceDefinitionsAsync = uwpHidDeviceEnumerator.GetConnectedDeviceDefinitionsAsync;
            }

            return(new DeviceFactory(
                       loggerFactory,
                       getConnectedDeviceDefinitionsAsync,
                       getDevice,
                       (c, cancellationToken) => Task.FromResult(c.DeviceType == DeviceType.Hid && (classGuid == null || classGuid.Value == c.ClassGuid))
                       ));
        }