# SPDX-License-Identifier: LGPL-2.1-or-later # # This file is formatted with Python Black # mypy: disable-error-code="misc" from tests.templates import Response, init_logger, ImplRequest import dbus import dbus.service from dbusmock import MOCK_IFACE from dataclasses import dataclass BUS_NAME = "org.freedesktop.impl.portal.Test" MAIN_OBJ = "/org/freedesktop/portal/desktop" SYSTEM_BUS = False MAIN_IFACE = "org.freedesktop.impl.portal.Usb" VERSION = 1 logger = init_logger(__name__) @dataclass class UsbParameters: delay: int response: int expect_close: bool filters: dict def load(mock, parameters={}): logger.debug(f"Loading parameters: {parameters}") assert not hasattr(mock, "usb_params") mock.usb_params = UsbParameters( delay=parameters.get("delay", 200), response=parameters.get("response", 0), expect_close=parameters.get("expect-close", False), filters=parameters.get("filters", {}), ) mock.AddProperties( MAIN_IFACE, dbus.Dictionary( { "version": dbus.UInt32(parameters.get("version", VERSION)), } ), ) @dbus.service.method( MAIN_IFACE, in_signature="ossa(sa{sv}a{sv})a{sv}", out_signature="ua{sv}", async_callbacks=("cb_success", "cb_error"), ) def AcquireDevices( self, handle, parent_window, app_id, devices, options, cb_success, cb_error, ): logger.debug( f"AcquireDevices({handle}, {parent_window}, {app_id}, {devices}, {options})" ) params = self.usb_params request = ImplRequest( self, BUS_NAME, handle, logger, cb_success, cb_error, ) def reply(): # no options supported assert not options devices_out = [] for device in devices: (id, info, access_options) = device props = info["properties"] allows_writable = params.filters.get("writable", True) needs_writable = access_options.get("writable", False) if needs_writable and not allows_writable: logger.debug(f"Skipping device {id} because it requires writable") continue needs_vendor = params.filters.get("vendor", None) needs_vendor = int(needs_vendor, 16) if needs_vendor else None vendor = props.get("ID_VENDOR_ID", None) vendor = int(vendor, 16) if vendor else None if needs_vendor is not None and needs_vendor != vendor: logger.debug( f"Skipping device {id} because it does not belong to vendor {needs_vendor:02x}" ) continue needs_model = params.filters.get("model", None) needs_model = int(needs_model, 16) if needs_model else None model = props.get("ID_MODEL_ID", None) model = int(model, 16) if model else None if needs_model is not None and needs_model != model: logger.debug( f"Skipping device {id} because it is not a model {needs_model:02x}" ) continue devices_out.append( dbus.Struct([id, access_options], signature="sa{sv}", variant_level=1) ) return Response( params.response, {"devices": dbus.Array(devices_out, signature="(sa{sv})", variant_level=1)}, ) if params.expect_close: request.wait_for_close() else: request.respond(reply, delay=params.delay) @dbus.service.method( MOCK_IFACE, in_signature="a{sv}", out_signature="", ) def SetSelectionFilters(self, filters): logger.debug(f"SetSelectionFilters({filters})") params = self.usb_params params.filters = filters