From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C68CCC4167B for ; Wed, 29 Nov 2023 15:25:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234900AbjK2PZA (ORCPT ); Wed, 29 Nov 2023 10:25:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234865AbjK2PY5 (ORCPT ); Wed, 29 Nov 2023 10:24:57 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DDEC184 for ; Wed, 29 Nov 2023 07:25:03 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12C1FC433C9; Wed, 29 Nov 2023 15:25:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271503; bh=lglUK6Ur3CdUwASQTgBslEe65vEhczn7ZV7KCziVP0g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=sxc4fHzh0Y2eCyN3G/k7rWHDOyvotcqkxnNlOupZYGA60Vu8k8v9V4HEn1M5DCzAl P24rYW7EvJ8OcZwP1+vryNP1tNiUXcjKNVLPVTUqWbwYwNW6lNX9gXnwprXWzIR1pd qxy9E5Fcn06mwO3aphaRu69QB76wATBhmf84K5poEnkewpsiWv9TxIPJb4nC8WJ4bt eqH35xNdtxQTLeii+XplLEaw4ABkB44PUXu2Js4BUmN+pdTqQo6jOvQjK5elfCgwoB ARgTMi3ykGZrRRZTsQSphhLFm+pOl46ee1qYXUZFfja+hkhq+/L1l9Q6flvbn6jSqY /KFgvBgn+U0IA== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:26 +0100 Subject: [PATCH 01/12] selftests/hid: vmtest.sh: update vm2c and container MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-1-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=1422; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=lglUK6Ur3CdUwASQTgBslEe65vEhczn7ZV7KCziVP0g=; b=UyNv9qDRZwVXeIiBK4TZRTOaBbeXhh9LFXi5nHBY/ucZyQcGfBVWczCmmvf+mWaKSYZfURa29 Lb2gKk+5bIvCRNcQDqCQMElrQSIDmEsYI2w4zQWhrEdwn6mWBbwJMkB X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org boot2container is now on an official project, so let's use that. The container image is now the same I use for the CI, so let's keep to it. Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/vmtest.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/hid/vmtest.sh b/tools/testing/selftest= s/hid/vmtest.sh index 4da48bf6b328..301b4e162336 100755 --- a/tools/testing/selftests/hid/vmtest.sh +++ b/tools/testing/selftests/hid/vmtest.sh @@ -19,12 +19,12 @@ esac SCRIPT_DIR=3D"$(dirname $(realpath $0))" OUTPUT_DIR=3D"$SCRIPT_DIR/results" KCONFIG_REL_PATHS=3D("${SCRIPT_DIR}/config" "${SCRIPT_DIR}/config.common" = "${SCRIPT_DIR}/config.${ARCH}") -B2C_URL=3D"https://gitlab.freedesktop.org/mupuf/boot2container/-/raw/maste= r/vm2c.py" +B2C_URL=3D"https://gitlab.freedesktop.org/gfx-ci/boot2container/-/raw/main= /vm2c.py" NUM_COMPILE_JOBS=3D"$(nproc)" LOG_FILE_BASE=3D"$(date +"hid_selftests.%Y-%m-%d_%H-%M-%S")" LOG_FILE=3D"${LOG_FILE_BASE}.log" EXIT_STATUS_FILE=3D"${LOG_FILE_BASE}.exit_status" -CONTAINER_IMAGE=3D"registry.freedesktop.org/libevdev/hid-tools/fedora/37:2= 023-02-17.1" +CONTAINER_IMAGE=3D"registry.freedesktop.org/bentiss/hid/fedora/39:2023-11-= 22.1" =20 TARGETS=3D"${TARGETS:=3D$(basename ${SCRIPT_DIR})}" DEFAULT_COMMAND=3D"pip3 install hid-tools; make -C tools/testing/selftests= TARGETS=3D${TARGETS} run_tests" --=20 2.41.0 From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 455F0C4167B for ; Wed, 29 Nov 2023 15:25:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234486AbjK2PZD (ORCPT ); Wed, 29 Nov 2023 10:25:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234898AbjK2PY7 (ORCPT ); Wed, 29 Nov 2023 10:24:59 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D22C484 for ; Wed, 29 Nov 2023 07:25:05 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 009D0C433C8; Wed, 29 Nov 2023 15:25:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271505; bh=d0j1ygzfv543NA+sGX2Z4uqQwtYj5yA4+tnlTa5g4Ko=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=sMmZgpkr3oSEc/hnNfjXgKBVCPQPCvRbhbHzQF5uJtId/6mLhP5rXV+DDtk8LCmnD Sa3Y+pLYDCIA0fzN0XfWuAoc7WT3onyTfP0FJdis9Uq0BuMCxTM+JXxx8vd9ciFnwH Cf2POVg+Kb0kYMOpvWC80x98O1IUxKf4TE3uUN0peBfWubb7jDhUztxYv5/kPtw0/M JxZ8ygFP9/koIQWymKarxiIi0YxTWA2Ur6Ohnx5nTEjhz50IICKQGiHXprOwMpSZHZ pRLUILFC4xEX/cJoPIb3GkGaiS2zu0kl/i1HoKcvyshAt88539vBzV/RcnHaf5oOPS Y4BH/5eDeZbqQ== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:27 +0100 Subject: [PATCH 02/12] selftests/hid: vmtest.sh: allow finer control on the build steps MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-2-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=3407; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=d0j1ygzfv543NA+sGX2Z4uqQwtYj5yA4+tnlTa5g4Ko=; b=936ntHKnOa4tMGXOqIzvQBJMwFxjDxpyeDuhAQllyO2dJ5tdmUXkhVz5Vm6nSJ8QcRRU2ElX6 oOlMwhR1YhLCVue2OBoZ1BqJ8PCkz6pFN+4gw3Pa+czVbhjmvqXw42+ X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org vmtest.sh works great for a one shot test, but not so much for CI where I want to build (with different configs) the bzImage in a separate job than the one I am running it. Add a "build_only" option to specify whether we need to boot the currently built kernel in the vm. Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/vmtest.sh | 42 ++++++++++++++++++++-----------= ---- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/tools/testing/selftests/hid/vmtest.sh b/tools/testing/selftest= s/hid/vmtest.sh index 301b4e162336..52ada972833b 100755 --- a/tools/testing/selftests/hid/vmtest.sh +++ b/tools/testing/selftests/hid/vmtest.sh @@ -32,7 +32,7 @@ DEFAULT_COMMAND=3D"pip3 install hid-tools; make -C tools/= testing/selftests TARGETS usage() { cat <] -- [] +Usage: $0 [-j N] [-s] [-b] [-d ] -- [] =20 is the command you would normally run when you are in the source kernel direcory. e.g: @@ -55,6 +55,7 @@ Options: =20 -u) Update the boot2container script to a newer version. -d) Update the output directory (default: ${OUTPUT_DIR}) + -b) Run the only build steps for the kernel and the selftests -j) Number of jobs for compilation, similar to -j in make (default: ${NUM_COMPILE_JOBS}) -s) Instead of powering off the VM, start an interactive @@ -191,8 +192,9 @@ main() local command=3D"${DEFAULT_COMMAND}" local update_b2c=3D"no" local debug_shell=3D"no" + local build_only=3D"no" =20 - while getopts ':hsud:j:' opt; do + while getopts ':hsud:j:b' opt; do case ${opt} in u) update_b2c=3D"yes" @@ -207,6 +209,9 @@ main() command=3D"/bin/sh" debug_shell=3D"yes" ;; + b) + build_only=3D"yes" + ;; h) usage exit 0 @@ -226,8 +231,7 @@ main() shift $((OPTIND -1)) =20 # trap 'catch "$?"' EXIT - - if [[ "${debug_shell}" =3D=3D "no" ]]; then + if [[ "${build_only}" =3D=3D "no" && "${debug_shell}" =3D=3D "no" ]]; then if [[ $# -eq 0 ]]; then echo "No command specified, will run ${DEFAULT_COMMAND} in the vm" else @@ -267,24 +271,26 @@ main() update_kconfig "${kernel_checkout}" "${kconfig_file}" =20 recompile_kernel "${kernel_checkout}" "${make_command}" + update_selftests "${kernel_checkout}" "${make_command}" =20 - if [[ "${update_b2c}" =3D=3D "no" && ! -f "${b2c}" ]]; then - echo "vm2c script not found in ${b2c}" - update_b2c=3D"yes" - fi + if [[ "${build_only}" =3D=3D "no" ]]; then + if [[ "${update_b2c}" =3D=3D "no" && ! -f "${b2c}" ]]; then + echo "vm2c script not found in ${b2c}" + update_b2c=3D"yes" + fi =20 - if [[ "${update_b2c}" =3D=3D "yes" ]]; then - download $B2C_URL $b2c - chmod +x $b2c - fi + if [[ "${update_b2c}" =3D=3D "yes" ]]; then + download $B2C_URL $b2c + chmod +x $b2c + fi =20 - update_selftests "${kernel_checkout}" "${make_command}" - run_vm "${kernel_checkout}" $b2c "${kernel_bzimage}" "${command}" - if [[ "${debug_shell}" !=3D "yes" ]]; then - echo "Logs saved in ${OUTPUT_DIR}/${LOG_FILE}" - fi + run_vm "${kernel_checkout}" $b2c "${kernel_bzimage}" "${command}" + if [[ "${debug_shell}" !=3D "yes" ]]; then + echo "Logs saved in ${OUTPUT_DIR}/${LOG_FILE}" + fi =20 - exit $(cat ${OUTPUT_DIR}/${EXIT_STATUS_FILE}) + exit $(cat ${OUTPUT_DIR}/${EXIT_STATUS_FILE}) + fi } =20 main "$@" --=20 2.41.0 From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0D366C07CB1 for ; Wed, 29 Nov 2023 15:25:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343497AbjK2PZF (ORCPT ); Wed, 29 Nov 2023 10:25:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34406 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234901AbjK2PZB (ORCPT ); Wed, 29 Nov 2023 10:25:01 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C7306BE for ; Wed, 29 Nov 2023 07:25:07 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E34D4C433CB; Wed, 29 Nov 2023 15:25:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271507; bh=kG2+ej6cJ+ghQo+0P11j+c5Gws+B/g/6ONT5dR7kBSg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dGCduNIIvZgqq/TxuYMezF3tHg4UfzJwkO+QFU+etNx5EnXi07/Dq/aHCLz5bQzqu gK9S/QFt7JL+C3Pw8OcXQ87oMJ47zQu7+pjtlmEvITlVIbzQm2JrmWf6/+nmUkP3ei 48NIvmprJGh8PHWIGPSIkreSxwNU6dSty+MOxBErDg7y53pMTifxQPTeCRBnV8HQoY lrEs1zX8tXjYCh8sdzhrL3rczWjkrjGNKX+62qTgcpCcT6+MDHCbOBfPWbB0JeCdxE q+4/+TJh42PO2n+dmLa7RUMdn56EBVFUDhr8aQB/dwvilxA+g/qkGw0nttTgwOtdne nzqoAeVbNJyLg== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:28 +0100 Subject: [PATCH 03/12] selftests/hid: base: allow for multiple skip_if_uhdev MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-3-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=1211; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=kG2+ej6cJ+ghQo+0P11j+c5Gws+B/g/6ONT5dR7kBSg=; b=cRFybPnwZ68SH5mCbsRVxDJcFgImN6Y5PIICvbba808TbqdFz1Ch3p8CQc+UIyA6tVhJaY+bY zLd5oD03G7bD+zF5g/bCAs6eMhzDrtSDwOw2wyqAvs2ZkwA226KbLuS X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We can actually have multiple occurences of `skip_if_uhdev` if we follow the information from the pytest doc[0]. This is not immediately used, but can be if we need multiple conditions on a given test. [0] https://docs.pytest.org/en/latest/historical-notes.html#update-marker-c= ode Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/tests/base.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/testing/selftests/hid/tests/base.py b/tools/testing/self= tests/hid/tests/base.py index 1305cfc9646e..5d9c26dfc460 100644 --- a/tools/testing/selftests/hid/tests/base.py +++ b/tools/testing/selftests/hid/tests/base.py @@ -238,8 +238,7 @@ class BaseTestCase: try: with HIDTestUdevRule.instance(): with new_uhdev as self.uhdev: - skip_cond =3D request.node.get_closest_marker("ski= p_if_uhdev") - if skip_cond: + for skip_cond in request.node.iter_markers("skip_i= f_uhdev"): test, message, *rest =3D skip_cond.args =20 if test(self.uhdev): --=20 2.41.0 From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 85DBDC07CB1 for ; Wed, 29 Nov 2023 15:25:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234215AbjK2PZH (ORCPT ); Wed, 29 Nov 2023 10:25:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234918AbjK2PZE (ORCPT ); Wed, 29 Nov 2023 10:25:04 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B44FF98 for ; Wed, 29 Nov 2023 07:25:09 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D15A0C43391; Wed, 29 Nov 2023 15:25:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271509; bh=Nb8tm7B+NGdmZAEx/i4rqoigQ/eiqRZPYosDwPWo2AY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=aaCfdq/T8P3k/Qh4KXZku0Z8B6cIu0RbB0RNZZzkHHLmxHjrN4it8JR0XeEBV0Cf0 QPI/cHNqaekn6Itmep5rX9+ohdRNG2iK/P8bCByOn1VCUhnv5b/AfQdK/h25N2lBts 9vQ42H8RWu9a4l4+sm8ziQbwuAMcGNcNOPcQpfXtoO+gSSejcGFW24/wWczAJDe4Dm XIHVKaoLbzdJNsVKlXAUuP9NAbbQf1zAmj4MHPyP5+4qTPLboI1s4ItCxh3OgEgqXb gfcE+JdDssCVAumDxPrgIORL3hA/oEFYeq+VdxUh3sz0jtp/twfIcrKPsd/laqirnA jetXg8F0898gw== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:29 +0100 Subject: [PATCH 04/12] selftests/hid: tablets: remove unused class MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-4-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=659; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=Nb8tm7B+NGdmZAEx/i4rqoigQ/eiqRZPYosDwPWo2AY=; b=PzPLUKbSzIb01Kpd2ou7OVM+vn83H+oaUcMIdpFBv7EfvQ2pYb8b3prdb4B/UOxafTCBqIaQR LmL0bOn3IM7ASYsWao6gT0wYsQYOl5E8zJrc5S695rHCF3mWCmjuqMc X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Looks like this is a leftover Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/tests/test_tablet.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/testing/selftests/hid/tests/test_tablet.py b/tools/testi= ng/selftests/hid/tests/test_tablet.py index 303ffff9ee8d..cd9c1269afa6 100644 --- a/tools/testing/selftests/hid/tests/test_tablet.py +++ b/tools/testing/selftests/hid/tests/test_tablet.py @@ -133,10 +133,6 @@ class PenState(Enum): return tuple() =20 =20 -class Data(object): - pass - - class Pen(object): def __init__(self, x, y): self.x =3D x --=20 2.41.0 From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9B12C4167B for ; Wed, 29 Nov 2023 15:25:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234717AbjK2PZW (ORCPT ); Wed, 29 Nov 2023 10:25:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54556 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234929AbjK2PZG (ORCPT ); Wed, 29 Nov 2023 10:25:06 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9FCC3C9 for ; Wed, 29 Nov 2023 07:25:11 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BFD61C433CB; Wed, 29 Nov 2023 15:25:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271511; bh=FgvDYTZPmqNfjQj10BxzNHCLREarvkKj4LedIEIJzdE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=eHzkmC9Ba0CB32ONG92dG26xVvf/wdMxIuSWquwWnsm0zTLr4zU8edPQtLqZGuu3t u9BgzP1CRgDG46RqPnNeX/SWOMIPbrfO5KEvt9xOdnu9uurXOvtMqWsSH0YRHQ0hB4 xJnXJNmvWyFvrCVXYb46E9jWaVhFoBHAZCVc/fhTeUXjQjopdsfI7rrMxdqrNvqBGK SBSbUEaLWDqWGUtR9juaMV1pIzhqwLV11oB8zAXw2hRTdCrkiRTiJs4NjDPYmC6qU1 1gYaFleLcdxyIRVBMm6YuEDRs9w8Oa5aw9eTCJ3I/rIlcl6Grn6cgoyNFWYKqpBcRF Z3tOV7nORK7JQ== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:30 +0100 Subject: [PATCH 05/12] selftests/hid: tablets: move the transitions to PenState MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-5-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=11653; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=FgvDYTZPmqNfjQj10BxzNHCLREarvkKj4LedIEIJzdE=; b=rqb4WviI1/OlPiyv8gdgY4LjcMWP4CqgreEQ5imq4IL4Gu7KVDcfT8eI653jGSOtBEdFdfY92 bVJXYFNFkBbAXXL0y1FZErxkblWGmyc7CMTE1qY78nEaLhzIJjPnqhz X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Those transitions have nothing to do with `Pen`, so migrate them to `PenState`. The hidden agenda is to remove `Pen` and integrate it into `PenDigitizer` so that we can tweak the events in each state to emulate firmware bugs. Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/tests/test_tablet.py | 212 +++++++++++--------= ---- 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/tools/testing/selftests/hid/tests/test_tablet.py b/tools/testi= ng/selftests/hid/tests/test_tablet.py index cd9c1269afa6..18961758e4aa 100644 --- a/tools/testing/selftests/hid/tests/test_tablet.py +++ b/tools/testing/selftests/hid/tests/test_tablet.py @@ -132,104 +132,8 @@ class PenState(Enum): =20 return tuple() =20 - -class Pen(object): - def __init__(self, x, y): - self.x =3D x - self.y =3D y - self.tipswitch =3D False - self.tippressure =3D 15 - self.azimuth =3D 0 - self.inrange =3D False - self.width =3D 10 - self.height =3D 10 - self.barrelswitch =3D False - self.invert =3D False - self.eraser =3D False - self.x_tilt =3D 0 - self.y_tilt =3D 0 - self.twist =3D 0 - self._old_values =3D None - self.current_state =3D None - - def _restore(self): - if self._old_values is not None: - for i in [ - "x", - "y", - "tippressure", - "azimuth", - "width", - "height", - "twist", - "x_tilt", - "y_tilt", - ]: - setattr(self, i, getattr(self._old_values, i)) - - def move_to(self, state): - # fill in the previous values - if self.current_state =3D=3D PenState.PEN_IS_OUT_OF_RANGE: - self._restore() - - print(f"\n *** pen is moving to {state} ***") - - if state =3D=3D PenState.PEN_IS_OUT_OF_RANGE: - self._old_values =3D copy.copy(self) - self.x =3D 0 - self.y =3D 0 - self.tipswitch =3D False - self.tippressure =3D 0 - self.azimuth =3D 0 - self.inrange =3D False - self.width =3D 0 - self.height =3D 0 - self.invert =3D False - self.eraser =3D False - self.x_tilt =3D 0 - self.y_tilt =3D 0 - self.twist =3D 0 - elif state =3D=3D PenState.PEN_IS_IN_RANGE: - self.tipswitch =3D False - self.inrange =3D True - self.invert =3D False - self.eraser =3D False - elif state =3D=3D PenState.PEN_IS_IN_CONTACT: - self.tipswitch =3D True - self.inrange =3D True - self.invert =3D False - self.eraser =3D False - elif state =3D=3D PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT: - self.tipswitch =3D False - self.inrange =3D True - self.invert =3D True - self.eraser =3D False - elif state =3D=3D PenState.PEN_IS_ERASING: - self.tipswitch =3D False - self.inrange =3D True - self.invert =3D True - self.eraser =3D True - - self.current_state =3D state - - def __assert_axis(self, evdev, axis, value): - if ( - axis =3D=3D libevdev.EV_KEY.BTN_TOOL_RUBBER - and evdev.value[libevdev.EV_KEY.BTN_TOOL_RUBBER] is None - ): - return - - assert ( - evdev.value[axis] =3D=3D value - ), f"assert evdev.value[{axis}] ({evdev.value[axis]}) !=3D {value}" - - def assert_expected_input_events(self, evdev): - assert evdev.value[libevdev.EV_ABS.ABS_X] =3D=3D self.x - assert evdev.value[libevdev.EV_ABS.ABS_Y] =3D=3D self.y - assert self.current_state =3D=3D PenState.from_evdev(evdev) - @staticmethod - def legal_transitions() -> Dict[str, Tuple[PenState, ...]]: + def legal_transitions() -> Dict[str, Tuple["PenState", ...]]: """This is the first half of the Windows Pen Implementation state = machine: we don't have Invert nor Erase bits, so just move in/out-of-range = or proximity. https://docs.microsoft.com/en-us/windows-hardware/design/component= -guidelines/windows-pen-states @@ -255,7 +159,7 @@ class Pen(object): } =20 @staticmethod - def legal_transitions_with_invert() -> Dict[str, Tuple[PenState, ...]]: + def legal_transitions_with_invert() -> Dict[str, Tuple["PenState", ...= ]]: """This is the second half of the Windows Pen Implementation state= machine: we now have Invert and Erase bits, so move in/out or proximity wit= h the intend to erase. @@ -293,7 +197,7 @@ class Pen(object): } =20 @staticmethod - def tolerated_transitions() -> Dict[str, Tuple[PenState, ...]]: + def tolerated_transitions() -> Dict[str, Tuple["PenState", ...]]: """This is not adhering to the Windows Pen Implementation state ma= chine but we should expect the kernel to behave properly, mostly for his= torical reasons.""" @@ -306,7 +210,7 @@ class Pen(object): } =20 @staticmethod - def tolerated_transitions_with_invert() -> Dict[str, Tuple[PenState, .= ..]]: + def tolerated_transitions_with_invert() -> Dict[str, Tuple["PenState",= ...]]: """This is the second half of the Windows Pen Implementation state= machine: we now have Invert and Erase bits, so move in/out or proximity wit= h the intend to erase. @@ -321,7 +225,7 @@ class Pen(object): } =20 @staticmethod - def broken_transitions() -> Dict[str, Tuple[PenState, ...]]: + def broken_transitions() -> Dict[str, Tuple["PenState", ...]]: """Those tests are definitely not part of the Windows specificatio= n. However, a half broken device might export those transitions. For example, a pen that has the eraser button might wobble between @@ -359,6 +263,102 @@ class Pen(object): } =20 =20 +class Pen(object): + def __init__(self, x, y): + self.x =3D x + self.y =3D y + self.tipswitch =3D False + self.tippressure =3D 15 + self.azimuth =3D 0 + self.inrange =3D False + self.width =3D 10 + self.height =3D 10 + self.barrelswitch =3D False + self.invert =3D False + self.eraser =3D False + self.x_tilt =3D 0 + self.y_tilt =3D 0 + self.twist =3D 0 + self._old_values =3D None + self.current_state =3D None + + def _restore(self): + if self._old_values is not None: + for i in [ + "x", + "y", + "tippressure", + "azimuth", + "width", + "height", + "twist", + "x_tilt", + "y_tilt", + ]: + setattr(self, i, getattr(self._old_values, i)) + + def move_to(self, state): + # fill in the previous values + if self.current_state =3D=3D PenState.PEN_IS_OUT_OF_RANGE: + self._restore() + + print(f"\n *** pen is moving to {state} ***") + + if state =3D=3D PenState.PEN_IS_OUT_OF_RANGE: + self._old_values =3D copy.copy(self) + self.x =3D 0 + self.y =3D 0 + self.tipswitch =3D False + self.tippressure =3D 0 + self.azimuth =3D 0 + self.inrange =3D False + self.width =3D 0 + self.height =3D 0 + self.invert =3D False + self.eraser =3D False + self.x_tilt =3D 0 + self.y_tilt =3D 0 + self.twist =3D 0 + elif state =3D=3D PenState.PEN_IS_IN_RANGE: + self.tipswitch =3D False + self.inrange =3D True + self.invert =3D False + self.eraser =3D False + elif state =3D=3D PenState.PEN_IS_IN_CONTACT: + self.tipswitch =3D True + self.inrange =3D True + self.invert =3D False + self.eraser =3D False + elif state =3D=3D PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT: + self.tipswitch =3D False + self.inrange =3D True + self.invert =3D True + self.eraser =3D False + elif state =3D=3D PenState.PEN_IS_ERASING: + self.tipswitch =3D False + self.inrange =3D True + self.invert =3D True + self.eraser =3D True + + self.current_state =3D state + + def __assert_axis(self, evdev, axis, value): + if ( + axis =3D=3D libevdev.EV_KEY.BTN_TOOL_RUBBER + and evdev.value[libevdev.EV_KEY.BTN_TOOL_RUBBER] is None + ): + return + + assert ( + evdev.value[axis] =3D=3D value + ), f"assert evdev.value[{axis}] ({evdev.value[axis]}) !=3D {value}" + + def assert_expected_input_events(self, evdev): + assert evdev.value[libevdev.EV_ABS.ABS_X] =3D=3D self.x + assert evdev.value[libevdev.EV_ABS.ABS_Y] =3D=3D self.y + assert self.current_state =3D=3D PenState.from_evdev(evdev) + + class PenDigitizer(base.UHIDTestDevice): def __init__( self, @@ -486,7 +486,7 @@ class BaseTest: @pytest.mark.parametrize("scribble", [True, False], ids=3D["scribb= le", "static"]) @pytest.mark.parametrize( "state_list", - [pytest.param(v, id=3Dk) for k, v in Pen.legal_transitions().i= tems()], + [pytest.param(v, id=3Dk) for k, v in PenState.legal_transition= s().items()], ) def test_valid_pen_states(self, state_list, scribble): """This is the first half of the Windows Pen Implementation st= ate machine: @@ -498,7 +498,7 @@ class BaseTest: @pytest.mark.parametrize("scribble", [True, False], ids=3D["scribb= le", "static"]) @pytest.mark.parametrize( "state_list", - [pytest.param(v, id=3Dk) for k, v in Pen.tolerated_transitions= ().items()], + [pytest.param(v, id=3Dk) for k, v in PenState.tolerated_transi= tions().items()], ) def test_tolerated_pen_states(self, state_list, scribble): """This is not adhering to the Windows Pen Implementation stat= e machine @@ -515,7 +515,7 @@ class BaseTest: "state_list", [ pytest.param(v, id=3Dk) - for k, v in Pen.legal_transitions_with_invert().items() + for k, v in PenState.legal_transitions_with_invert().items= () ], ) def test_valid_invert_pen_states(self, state_list, scribble): @@ -535,7 +535,7 @@ class BaseTest: "state_list", [ pytest.param(v, id=3Dk) - for k, v in Pen.tolerated_transitions_with_invert().items() + for k, v in PenState.tolerated_transitions_with_invert().i= tems() ], ) def test_tolerated_invert_pen_states(self, state_list, scribble): @@ -553,7 +553,7 @@ class BaseTest: @pytest.mark.parametrize("scribble", [True, False], ids=3D["scribb= le", "static"]) @pytest.mark.parametrize( "state_list", - [pytest.param(v, id=3Dk) for k, v in Pen.broken_transitions().= items()], + [pytest.param(v, id=3Dk) for k, v in PenState.broken_transitio= ns().items()], ) def test_tolerated_broken_pen_states(self, state_list, scribble): """Those tests are definitely not part of the Windows specific= ation. --=20 2.41.0 From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2937AC4167B for ; Wed, 29 Nov 2023 15:25:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234763AbjK2PZZ (ORCPT ); Wed, 29 Nov 2023 10:25:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54442 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234067AbjK2PZM (ORCPT ); Wed, 29 Nov 2023 10:25:12 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A92AE10E2 for ; Wed, 29 Nov 2023 07:25:13 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id ADEFCC433C7; Wed, 29 Nov 2023 15:25:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271513; bh=cc0b1jiuNKRXpLCKlecakBm8q8bu4sRt8EzldFhVXEg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=r8czLiG4SA/CrUJNFmFmVRqOyTquHJcSu4YN0Pglq3iArYsmbJL9uPF5mLJQxGkT6 V2ZDAZtjZbdUDb3nImKNxYc3yNN00wL87AWjRQ7Dp7ZDlxHrrwihQEPfuAYbL71qUh JPlXg3UMrdRUP/+bm7Yrcziqa/fnkdd9FXFLrjZ1/vf8w8q+NpRAK22KSyiX7uuqSf qIVDpYZd0ZyYoW8E+D+0d7YxnGdA9pG13y3m5Z0i02x4eSjM4LSQW+BzeEVUXoMSgY AcHhroL+tU1nPo9OVNwkuUh6ItLeuKTNXf9m+5RVgZOSnKm8L7UmJ8/esfn93JjdXH Qd4BUXYDPEz4w== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:31 +0100 Subject: [PATCH 06/12] selftests/hid: tablets: move move_to function to PenDigitizer MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-6-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=5281; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=cc0b1jiuNKRXpLCKlecakBm8q8bu4sRt8EzldFhVXEg=; b=s/G95xyyW0nb0zcopdvpLLf34B8+2cViUddub6Sm8ZpAJ8SZV9dQGN4Q8b8B6X1vmzjqn9E/u C3hARQugD3BBBvLb5+wTmL8/YyUyj4nUUQYyAAPdyH1FjyBEBuAish5 X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We can easily subclass PenDigitizer for introducing firmware bugs when subclassing Pen is harder. Move move_to from Pen to PenDigitizer so we get that ability Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/tests/test_tablet.py | 97 ++++++++++++--------= ---- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/tools/testing/selftests/hid/tests/test_tablet.py b/tools/testi= ng/selftests/hid/tests/test_tablet.py index 18961758e4aa..44a004ca69d1 100644 --- a/tools/testing/selftests/hid/tests/test_tablet.py +++ b/tools/testing/selftests/hid/tests/test_tablet.py @@ -282,7 +282,7 @@ class Pen(object): self._old_values =3D None self.current_state =3D None =20 - def _restore(self): + def restore(self): if self._old_values is not None: for i in [ "x", @@ -297,50 +297,8 @@ class Pen(object): ]: setattr(self, i, getattr(self._old_values, i)) =20 - def move_to(self, state): - # fill in the previous values - if self.current_state =3D=3D PenState.PEN_IS_OUT_OF_RANGE: - self._restore() - - print(f"\n *** pen is moving to {state} ***") - - if state =3D=3D PenState.PEN_IS_OUT_OF_RANGE: - self._old_values =3D copy.copy(self) - self.x =3D 0 - self.y =3D 0 - self.tipswitch =3D False - self.tippressure =3D 0 - self.azimuth =3D 0 - self.inrange =3D False - self.width =3D 0 - self.height =3D 0 - self.invert =3D False - self.eraser =3D False - self.x_tilt =3D 0 - self.y_tilt =3D 0 - self.twist =3D 0 - elif state =3D=3D PenState.PEN_IS_IN_RANGE: - self.tipswitch =3D False - self.inrange =3D True - self.invert =3D False - self.eraser =3D False - elif state =3D=3D PenState.PEN_IS_IN_CONTACT: - self.tipswitch =3D True - self.inrange =3D True - self.invert =3D False - self.eraser =3D False - elif state =3D=3D PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT: - self.tipswitch =3D False - self.inrange =3D True - self.invert =3D True - self.eraser =3D False - elif state =3D=3D PenState.PEN_IS_ERASING: - self.tipswitch =3D False - self.inrange =3D True - self.invert =3D True - self.eraser =3D True - - self.current_state =3D state + def backup(self): + self._old_values =3D copy.copy(self) =20 def __assert_axis(self, evdev, axis, value): if ( @@ -384,6 +342,51 @@ class PenDigitizer(base.UHIDTestDevice): continue self.fields =3D [f.usage_name for f in r] =20 + def move_to(self, pen, state): + # fill in the previous values + if pen.current_state =3D=3D PenState.PEN_IS_OUT_OF_RANGE: + pen.restore() + + print(f"\n *** pen is moving to {state} ***") + + if state =3D=3D PenState.PEN_IS_OUT_OF_RANGE: + pen.backup() + pen.x =3D 0 + pen.y =3D 0 + pen.tipswitch =3D False + pen.tippressure =3D 0 + pen.azimuth =3D 0 + pen.inrange =3D False + pen.width =3D 0 + pen.height =3D 0 + pen.invert =3D False + pen.eraser =3D False + pen.x_tilt =3D 0 + pen.y_tilt =3D 0 + pen.twist =3D 0 + elif state =3D=3D PenState.PEN_IS_IN_RANGE: + pen.tipswitch =3D False + pen.inrange =3D True + pen.invert =3D False + pen.eraser =3D False + elif state =3D=3D PenState.PEN_IS_IN_CONTACT: + pen.tipswitch =3D True + pen.inrange =3D True + pen.invert =3D False + pen.eraser =3D False + elif state =3D=3D PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT: + pen.tipswitch =3D False + pen.inrange =3D True + pen.invert =3D True + pen.eraser =3D False + elif state =3D=3D PenState.PEN_IS_ERASING: + pen.tipswitch =3D False + pen.inrange =3D True + pen.invert =3D True + pen.eraser =3D True + + pen.current_state =3D state + def event(self, pen): rs =3D [] r =3D self.create_report(application=3Dself.cur_application, data= =3Dpen) @@ -462,7 +465,7 @@ class BaseTest: cur_state =3D PenState.PEN_IS_OUT_OF_RANGE =20 p =3D Pen(50, 60) - p.move_to(PenState.PEN_IS_OUT_OF_RANGE) + uhdev.move_to(p, PenState.PEN_IS_OUT_OF_RANGE) events =3D self.post(uhdev, p) self.validate_transitions(cur_state, p, evdev, events) =20 @@ -475,7 +478,7 @@ class BaseTest: events =3D self.post(uhdev, p) self.validate_transitions(cur_state, p, evdev, events) assert len(events) >=3D 3 # X, Y, SYN - p.move_to(state) + uhdev.move_to(p, state) if scribble and state !=3D PenState.PEN_IS_OUT_OF_RANGE: p.x +=3D 1 p.y -=3D 1 --=20 2.41.0 From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8B91DC4167B for ; Wed, 29 Nov 2023 15:25:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343518AbjK2PZ2 (ORCPT ); Wed, 29 Nov 2023 10:25:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54556 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234901AbjK2PZO (ORCPT ); Wed, 29 Nov 2023 10:25:14 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B8D581705 for ; Wed, 29 Nov 2023 07:25:15 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9C383C433D9; Wed, 29 Nov 2023 15:25:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271515; bh=ALQSUwIpXqcEh03ppshskh+FaGQmb8S9LPkrgK0UVXM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pjfaA5lG4wRnePTeuMezTeQNR3cQJMV+w9wh7qyCxTfSh6HoR2K587L8Gq9hpx0n7 uEwbK6mH1stOabGtj/fUMIf4ZqOty9O96MhUWSmBfe8nHraYdmYpHZQw0D4g1YfNlA jckFEC2XQ2BWf1wIUrX4H7/jJSTui7qNmQeZBd4LRrfAA/0sEm7i5tbEeTHEA2XHVn fPuWhSk3a+aHdaAO7ncU88ZQaIlo3Nn9ulhFrJWSBnBX5lYtCPi076CQOOcCr55b39 ozIgyrKLSd5GV20l7uMyuv/nUEM5l4QRrtLlG/iOtQPRhiwAExMOVaXX41uiBDRjS/ NDVoLiegViOtQ== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:32 +0100 Subject: [PATCH 07/12] selftests/hid: tablets: do not set invert when the eraser is used MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-7-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=1038; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=ALQSUwIpXqcEh03ppshskh+FaGQmb8S9LPkrgK0UVXM=; b=Ww9wUd/GRVTn1WpgOseXPPpOG+0ScJMar5njGQwo+gu43hi61Hw4ji4jWyhXEkih6ES2OAmJA RTNvk9zuLSEBut7pBFs6A9moqRluGVPc7wrwJCOk1f4lYJZpQ+tLIs2 X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Turns out that the chart from Microsoft is not exactly what I got here: when the rubber is used, and is touching the surface, invert can (should) be set to 0... [0] https://learn.microsoft.com/en-us/windows-hardware/design/component-gui= delines/windows-pen-states Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/tests/test_tablet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/hid/tests/test_tablet.py b/tools/testi= ng/selftests/hid/tests/test_tablet.py index 44a004ca69d1..f93dfbb2a3e5 100644 --- a/tools/testing/selftests/hid/tests/test_tablet.py +++ b/tools/testing/selftests/hid/tests/test_tablet.py @@ -382,7 +382,7 @@ class PenDigitizer(base.UHIDTestDevice): elif state =3D=3D PenState.PEN_IS_ERASING: pen.tipswitch =3D False pen.inrange =3D True - pen.invert =3D True + pen.invert =3D False pen.eraser =3D True =20 pen.current_state =3D state --=20 2.41.0 From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AFEE0C4167B for ; Wed, 29 Nov 2023 15:56:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343534AbjK2PZn (ORCPT ); Wed, 29 Nov 2023 10:25:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234997AbjK2PZR (ORCPT ); Wed, 29 Nov 2023 10:25:17 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E90A61719 for ; Wed, 29 Nov 2023 07:25:17 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8DBB9C433CA; Wed, 29 Nov 2023 15:25:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271517; bh=XtPjsU5+IxLgDeg42cN6iOZ79VywBRfgVyknH2ur/4A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NZpcLgMO9RqQMQczNI7n38lEze9h5miaSq4hI89SWSIpk2HAhAo9CDwIqMy5O7lxt 5bfCuMKD9RpgIoLO6lEt4cOjT87ODQrApuUOHJ2XhKs7zcV1M83MJljjlVgwUFURj8 UdYKKMlThyzVjWYhbBbFDTsUIHhxLTCNw61Y++DDOzokm4mvuja1onzdvhkOcNADVb aq9kD4Tg9gHNQisSd0Vv9HyEa9YVbG3B/yen1428IcJxG5mUhp4eNLG3m+1mrrce+C LxzTK3uVtOx/BvCFBDyPJKsme4n9mf94OKvP2FY9LhuTaHRcpasx3gopkZu3ARvUn9 IRADik8d2NnIA== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:33 +0100 Subject: [PATCH 08/12] selftests/hid: tablets: set initial data for tilt/twist MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-8-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=1586; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=XtPjsU5+IxLgDeg42cN6iOZ79VywBRfgVyknH2ur/4A=; b=CPZpA+NacCCwdjXGsWjew6pe/NmSHolAtr5gZ0Tj4ZfJt7ZIeCAFk1zsMRYilllE3NU0JJ383 cvHqBfw/8PtAUGPbAOezZ4JgNTtWrxmh7JyiNl/HAScTMAnJQ5iLWgh X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Avoids getting a null event when these usages are set Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/tests/test_tablet.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/hid/tests/test_tablet.py b/tools/testi= ng/selftests/hid/tests/test_tablet.py index f93dfbb2a3e5..83f6501fe984 100644 --- a/tools/testing/selftests/hid/tests/test_tablet.py +++ b/tools/testing/selftests/hid/tests/test_tablet.py @@ -276,9 +276,9 @@ class Pen(object): self.barrelswitch =3D False self.invert =3D False self.eraser =3D False - self.x_tilt =3D 0 - self.y_tilt =3D 0 - self.twist =3D 0 + self.xtilt =3D 1 + self.ytilt =3D 1 + self.twist =3D 1 self._old_values =3D None self.current_state =3D None =20 @@ -292,8 +292,8 @@ class Pen(object): "width", "height", "twist", - "x_tilt", - "y_tilt", + "xtilt", + "ytilt", ]: setattr(self, i, getattr(self._old_values, i)) =20 @@ -361,8 +361,8 @@ class PenDigitizer(base.UHIDTestDevice): pen.height =3D 0 pen.invert =3D False pen.eraser =3D False - pen.x_tilt =3D 0 - pen.y_tilt =3D 0 + pen.xtilt =3D 0 + pen.ytilt =3D 0 pen.twist =3D 0 elif state =3D=3D PenState.PEN_IS_IN_RANGE: pen.tipswitch =3D False --=20 2.41.0 From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B95BC4167B for ; Wed, 29 Nov 2023 15:56:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234633AbjK2P4l (ORCPT ); Wed, 29 Nov 2023 10:56:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343507AbjK2PZY (ORCPT ); Wed, 29 Nov 2023 10:25:24 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D0A791986 for ; Wed, 29 Nov 2023 07:25:19 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7D4FFC433CB; Wed, 29 Nov 2023 15:25:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271519; bh=uqWfmCl2vZTNBGQW3I2y+s3kBWYZ2gqQvlfYZ2vvT24=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RkeJh43TIojQnFOoY4jFFa2st09sE+PdhPqWNeVh/X/msl9+70cCLeVMUeAX8vuOG DecouLITgSvjFe3OUx5fVvAowgTy6gsQzUNxso5bSQ8L3PJRGwL3kU/5DU4/5pCBhj yZOMBzgV3Pq6+XaZSCzgJpmR5VvdWAgvlLwZD/eEX5sFPNIkCYhz14WdgcY5Vw1fIv mnypRXDmRI3yEWn9TawdwzzLNyyz6WHfl0Yd3zPhuH8qzWud2f8rVgfJKT/829TE6J VsFsmfaNAyPoo0QyuqSIeuPB7wcGar/keQg2Q2BOHT1uWWn72S+atqxa+3LbGjQJxX 3+TLxilJN33rw== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:34 +0100 Subject: [PATCH 09/12] selftests/hid: tablets: add variants of states with buttons MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-9-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=11152; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=uqWfmCl2vZTNBGQW3I2y+s3kBWYZ2gqQvlfYZ2vvT24=; b=7yIyysCibofBZjqn46A2ADLyBatKwXq0y/QHWgBWB8QcYlPDNni4VuDB2fJmvOL0NV4hgdYSS eqFgz11FF0vDEWRrkz0Ig9ABCir9m8sBa26D2iNC7zIHFZSAJdCxFJe X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Turns out that there are transitions that are unlikely to happen: for example, having both the tip switch and a button being changed at the same time (in the same report) would require either a very talented and precise user or a very bad hardware with a very low sampling rate. So instead of manually building the button test by hand and forgetting about some cases, let's reuse the state machine and transitions we have. This patch only adds the states and the valid transitions. The actual tests will be replaced later. Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/tests/test_tablet.py | 170 +++++++++++++++++++= ++-- 1 file changed, 157 insertions(+), 13 deletions(-) diff --git a/tools/testing/selftests/hid/tests/test_tablet.py b/tools/testi= ng/selftests/hid/tests/test_tablet.py index 83f6501fe984..80269d1a0f0a 100644 --- a/tools/testing/selftests/hid/tests/test_tablet.py +++ b/tools/testing/selftests/hid/tests/test_tablet.py @@ -21,22 +21,66 @@ logger =3D logging.getLogger("hidtools.test.tablet") class PenState(Enum): """Pen states according to Microsoft reference: https://docs.microsoft.com/en-us/windows-hardware/design/component-gui= delines/windows-pen-states - """ =20 - PEN_IS_OUT_OF_RANGE =3D (False, None) - PEN_IS_IN_RANGE =3D (False, libevdev.EV_KEY.BTN_TOOL_PEN) - PEN_IS_IN_CONTACT =3D (True, libevdev.EV_KEY.BTN_TOOL_PEN) - PEN_IS_IN_RANGE_WITH_ERASING_INTENT =3D (False, libevdev.EV_KEY.BTN_TO= OL_RUBBER) - PEN_IS_ERASING =3D (True, libevdev.EV_KEY.BTN_TOOL_RUBBER) + We extend it with the various buttons when we need to check them. + """ =20 - def __init__(self, touch, tool): + PEN_IS_OUT_OF_RANGE =3D (False, None, None) + PEN_IS_IN_RANGE =3D (False, libevdev.EV_KEY.BTN_TOOL_PEN, None) + PEN_IS_IN_RANGE_WITH_BUTTON =3D ( + False, + libevdev.EV_KEY.BTN_TOOL_PEN, + libevdev.EV_KEY.BTN_STYLUS, + ) + PEN_IS_IN_RANGE_WITH_SECOND_BUTTON =3D ( + False, + libevdev.EV_KEY.BTN_TOOL_PEN, + libevdev.EV_KEY.BTN_STYLUS2, + ) + PEN_IS_IN_CONTACT =3D (True, libevdev.EV_KEY.BTN_TOOL_PEN, None) + PEN_IS_IN_CONTACT_WITH_BUTTON =3D ( + True, + libevdev.EV_KEY.BTN_TOOL_PEN, + libevdev.EV_KEY.BTN_STYLUS, + ) + PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON =3D ( + True, + libevdev.EV_KEY.BTN_TOOL_PEN, + libevdev.EV_KEY.BTN_STYLUS2, + ) + PEN_IS_IN_RANGE_WITH_ERASING_INTENT =3D (False, libevdev.EV_KEY.BTN_TO= OL_RUBBER, None) + PEN_IS_IN_RANGE_WITH_ERASING_INTENT_WITH_BUTTON =3D ( + False, + libevdev.EV_KEY.BTN_TOOL_RUBBER, + libevdev.EV_KEY.BTN_STYLUS, + ) + PEN_IS_IN_RANGE_WITH_ERASING_INTENT_WITH_SECOND_BUTTON =3D ( + False, + libevdev.EV_KEY.BTN_TOOL_RUBBER, + libevdev.EV_KEY.BTN_STYLUS2, + ) + PEN_IS_ERASING =3D (True, libevdev.EV_KEY.BTN_TOOL_RUBBER, None) + PEN_IS_ERASING_WITH_BUTTON =3D ( + True, + libevdev.EV_KEY.BTN_TOOL_RUBBER, + libevdev.EV_KEY.BTN_STYLUS, + ) + PEN_IS_ERASING_WITH_SECOND_BUTTON =3D ( + True, + libevdev.EV_KEY.BTN_TOOL_RUBBER, + libevdev.EV_KEY.BTN_STYLUS2, + ) + + def __init__(self, touch, tool, button): self.touch =3D touch self.tool =3D tool + self.button =3D button =20 @classmethod def from_evdev(cls, evdev) -> "PenState": touch =3D bool(evdev.value[libevdev.EV_KEY.BTN_TOUCH]) tool =3D None + button =3D None if ( evdev.value[libevdev.EV_KEY.BTN_TOOL_RUBBER] and not evdev.value[libevdev.EV_KEY.BTN_TOOL_PEN] @@ -53,7 +97,17 @@ class PenState(Enum): ): raise ValueError("2 tools are not allowed") =20 - return cls((touch, tool)) + # we take only the highest button in account + for b in [libevdev.EV_KEY.BTN_STYLUS, libevdev.EV_KEY.BTN_STYLUS2]: + if bool(evdev.value[b]): + button =3D b + + # the kernel tends to insert an EV_SYN once removing the tool, so + # the button will be released after + if tool is None: + button =3D None + + return cls((touch, tool, button)) =20 def apply(self, events) -> "PenState": if libevdev.EV_SYN.SYN_REPORT in events: @@ -62,6 +116,8 @@ class PenState(Enum): touch_found =3D False tool =3D self.tool tool_found =3D False + button =3D self.button + button_found =3D False =20 for ev in events: if ev =3D=3D libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH): @@ -76,12 +132,22 @@ class PenState(Enum): if tool_found: raise ValueError(f"duplicated BTN_TOOL_* in {events}") tool_found =3D True - if ev.value: - tool =3D ev.code - else: - tool =3D None + tool =3D ev.code if ev.value else None + elif ev in ( + libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS), + libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS2), + ): + if button_found: + raise ValueError(f"duplicated BTN_STYLUS* in {events}") + button_found =3D True + button =3D ev.code if ev.value else None =20 - new_state =3D PenState((touch, tool)) + # the kernel tends to insert an EV_SYN once removing the tool, so + # the button will be released after + if tool is None: + button =3D None + + new_state =3D PenState((touch, tool, button)) assert ( new_state in self.valid_transitions() ), f"moving from {self} to {new_state} is forbidden" @@ -97,14 +163,20 @@ class PenState(Enum): return ( PenState.PEN_IS_OUT_OF_RANGE, PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, PenState.PEN_IS_ERASING, ) =20 if self =3D=3D PenState.PEN_IS_IN_RANGE: return ( PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, PenState.PEN_IS_OUT_OF_RANGE, PenState.PEN_IS_IN_CONTACT, ) @@ -112,6 +184,8 @@ class PenState(Enum): if self =3D=3D PenState.PEN_IS_IN_CONTACT: return ( PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, PenState.PEN_IS_IN_RANGE, PenState.PEN_IS_OUT_OF_RANGE, ) @@ -130,6 +204,38 @@ class PenState(Enum): PenState.PEN_IS_OUT_OF_RANGE, ) =20 + if self =3D=3D PenState.PEN_IS_IN_RANGE_WITH_BUTTON: + return ( + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_OUT_OF_RANGE, + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + ) + + if self =3D=3D PenState.PEN_IS_IN_CONTACT_WITH_BUTTON: + return ( + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_OUT_OF_RANGE, + ) + + if self =3D=3D PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON: + return ( + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_OUT_OF_RANGE, + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, + ) + + if self =3D=3D PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON: + return ( + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + PenState.PEN_IS_OUT_OF_RANGE, + ) + return tuple() =20 @staticmethod @@ -364,26 +470,64 @@ class PenDigitizer(base.UHIDTestDevice): pen.xtilt =3D 0 pen.ytilt =3D 0 pen.twist =3D 0 + pen.barrelswitch =3D False + pen.secondarybarrelswitch =3D False elif state =3D=3D PenState.PEN_IS_IN_RANGE: pen.tipswitch =3D False pen.inrange =3D True pen.invert =3D False pen.eraser =3D False + pen.barrelswitch =3D False + pen.secondarybarrelswitch =3D False elif state =3D=3D PenState.PEN_IS_IN_CONTACT: pen.tipswitch =3D True pen.inrange =3D True pen.invert =3D False pen.eraser =3D False + pen.barrelswitch =3D False + pen.secondarybarrelswitch =3D False + elif state =3D=3D PenState.PEN_IS_IN_RANGE_WITH_BUTTON: + pen.tipswitch =3D False + pen.inrange =3D True + pen.invert =3D False + pen.eraser =3D False + pen.barrelswitch =3D True + pen.secondarybarrelswitch =3D False + elif state =3D=3D PenState.PEN_IS_IN_CONTACT_WITH_BUTTON: + pen.tipswitch =3D True + pen.inrange =3D True + pen.invert =3D False + pen.eraser =3D False + pen.barrelswitch =3D True + pen.secondarybarrelswitch =3D False + elif state =3D=3D PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON: + pen.tipswitch =3D False + pen.inrange =3D True + pen.invert =3D False + pen.eraser =3D False + pen.barrelswitch =3D False + pen.secondarybarrelswitch =3D True + elif state =3D=3D PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON: + pen.tipswitch =3D True + pen.inrange =3D True + pen.invert =3D False + pen.eraser =3D False + pen.barrelswitch =3D False + pen.secondarybarrelswitch =3D True elif state =3D=3D PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT: pen.tipswitch =3D False pen.inrange =3D True pen.invert =3D True pen.eraser =3D False + pen.barrelswitch =3D False + pen.secondarybarrelswitch =3D False elif state =3D=3D PenState.PEN_IS_ERASING: pen.tipswitch =3D False pen.inrange =3D True pen.invert =3D False pen.eraser =3D True + pen.barrelswitch =3D False + pen.secondarybarrelswitch =3D False =20 pen.current_state =3D state =20 --=20 2.41.0 From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1383BC10DAA for ; Wed, 29 Nov 2023 15:56:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343863AbjK2P0E (ORCPT ); Wed, 29 Nov 2023 10:26:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53104 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235024AbjK2PZg (ORCPT ); Wed, 29 Nov 2023 10:25:36 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DA55910C4 for ; Wed, 29 Nov 2023 07:25:21 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 74B3CC433C7; Wed, 29 Nov 2023 15:25:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271521; bh=gEeyh8PcwmBsx5enMTqDdJ7sk3c2gLkm4hxwW8bPHuU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=HMD1DkvkjBXpqBr/IJYpJ5HptidFKUaqZ5CyUUjKFSBMGwTnl4702FFCMb7CENBCv LJBRiniiODMa9Vpk5fMXl0PO0BgNzL8PZXrofC/7fVBVczJr+lZxZOl3bh8VfmobCo A64KgpMqxR6X8CbMrhLJObq+z8d+B2UWhCDeFGrOgJKmC6/DKVpm9mvH/LZvNa74h1 n5NhaPhVGyaikqR+IegGJ9QhQqKDrC/2f56e7kbAHbSFZ23vEm+DvqgoxsHEZltF/t +6uVpJEXGRUjN1QpeY5YvClVQ59v+vO0Q4e0tHmzmlsR4NoP22wYrzhbU2QPYTJZ2N 1dY81DLGvh3Vg== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:35 +0100 Subject: [PATCH 10/12] selftests/hid: tablets: convert the primary button tests MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-10-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=9157; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=gEeyh8PcwmBsx5enMTqDdJ7sk3c2gLkm4hxwW8bPHuU=; b=mafe8eed3tP3bUO98NSU3Gy+ANCreRp7ZV5qkx9CIOdaGD87Lzbb4Ic1lIbw4LyfUymNqZVNl mvEMPzQaS/+AgKQvpduAKCxwgi4gbhF1Mh6biwGWnZB1Ok8odqiB7kX X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We get more descriptive in what we are doing, and also get more information of what is actually being tested. Instead of having a non exhaustive button changes that are semi-randomly done, we can describe all the states we want to test. Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/tests/test_tablet.py | 165 ++++++++++---------= ---- 1 file changed, 69 insertions(+), 96 deletions(-) diff --git a/tools/testing/selftests/hid/tests/test_tablet.py b/tools/testi= ng/selftests/hid/tests/test_tablet.py index 80269d1a0f0a..440a87170db1 100644 --- a/tools/testing/selftests/hid/tests/test_tablet.py +++ b/tools/testing/selftests/hid/tests/test_tablet.py @@ -302,6 +302,55 @@ class PenState(Enum): ), } =20 + @staticmethod + def legal_transitions_with_primary_button() -> Dict[str, Tuple["PenSta= te", ...]]: + """We revisit the Windows Pen Implementation state machine: + we now have a primary button. + """ + return { + "hover-button": (PenState.PEN_IS_IN_RANGE_WITH_BUTTON,), + "hover-button -> out-of-range": ( + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_OUT_OF_RANGE, + ), + "in-range -> button-press": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + ), + "in-range -> button-press -> button-release": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_IN_RANGE, + ), + "in-range -> touch -> button-press -> button-release": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + PenState.PEN_IS_IN_CONTACT, + ), + "in-range -> touch -> button-press -> release -> button-releas= e": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_IN_RANGE, + ), + "in-range -> button-press -> touch -> release -> button-releas= e": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_IN_RANGE, + ), + "in-range -> button-press -> touch -> button-release -> releas= e": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_RANGE, + ), + } + @staticmethod def tolerated_transitions() -> Dict[str, Tuple["PenState", ...]]: """This is not adhering to the Windows Pen Implementation state ma= chine @@ -645,7 +694,10 @@ class BaseTest: @pytest.mark.parametrize("scribble", [True, False], ids=3D["scribb= le", "static"]) @pytest.mark.parametrize( "state_list", - [pytest.param(v, id=3Dk) for k, v in PenState.tolerated_transi= tions().items()], + [ + pytest.param(v, id=3Dk) + for k, v in PenState.tolerated_transitions().items() + ], ) def test_tolerated_pen_states(self, state_list, scribble): """This is not adhering to the Windows Pen Implementation stat= e machine @@ -653,6 +705,22 @@ class BaseTest: reasons.""" self._test_states(state_list, scribble) =20 + @pytest.mark.skip_if_uhdev( + lambda uhdev: "Barrel Switch" not in uhdev.fields, + "Device not compatible, missing Barrel Switch usage", + ) + @pytest.mark.parametrize("scribble", [True, False], ids=3D["scribb= le", "static"]) + @pytest.mark.parametrize( + "state_list", + [ + pytest.param(v, id=3Dk) + for k, v in PenState.legal_transitions_with_primary_button= ().items() + ], + ) + def test_valid_primary_button_pen_states(self, state_list, scribbl= e): + """Rework the transition state machine by adding the primary b= utton.""" + self._test_states(state_list, scribble) + @pytest.mark.skip_if_uhdev( lambda uhdev: "Invert" not in uhdev.fields, "Device not compatible, missing Invert usage", @@ -710,101 +778,6 @@ class BaseTest: state machine.""" self._test_states(state_list, scribble) =20 - @pytest.mark.skip_if_uhdev( - lambda uhdev: "Barrel Switch" not in uhdev.fields, - "Device not compatible, missing Barrel Switch usage", - ) - def test_primary_button(self): - """Primary button (stylus) pressed, reports as pressed even wh= ile hovering. - Actual reporting from the device: hid=3DTIPSWITCH,BARRELSWITCH= ,INRANGE (code=3DTOUCH,STYLUS,PEN): - { 0, 0, 1 } <- hover - { 0, 1, 1 } <- primary button pressed - { 0, 1, 1 } <- liftoff - { 0, 0, 0 } <- leaves - """ - - uhdev =3D self.uhdev - evdev =3D uhdev.get_evdev() - - p =3D Pen(50, 60) - p.inrange =3D True - events =3D self.post(uhdev, p) - assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1) in= events - assert evdev.value[libevdev.EV_ABS.ABS_X] =3D=3D 50 - assert evdev.value[libevdev.EV_ABS.ABS_Y] =3D=3D 60 - assert not evdev.value[libevdev.EV_KEY.BTN_STYLUS] - - p.barrelswitch =3D True - events =3D self.post(uhdev, p) - assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 1) in e= vents - - p.x +=3D 1 - p.y -=3D 1 - events =3D self.post(uhdev, p) - assert len(events) =3D=3D 3 # X, Y, SYN - assert libevdev.InputEvent(libevdev.EV_ABS.ABS_X, 51) in events - assert libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, 59) in events - - p.barrelswitch =3D False - events =3D self.post(uhdev, p) - assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 0) in e= vents - - p.inrange =3D False - events =3D self.post(uhdev, p) - assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 0) in= events - - @pytest.mark.skip_if_uhdev( - lambda uhdev: "Barrel Switch" not in uhdev.fields, - "Device not compatible, missing Barrel Switch usage", - ) - def test_contact_primary_button(self): - """Primary button (stylus) pressed, reports as pressed even wh= ile hovering. - Actual reporting from the device: hid=3DTIPSWITCH,BARRELSWITCH= ,INRANGE (code=3DTOUCH,STYLUS,PEN): - { 0, 0, 1 } <- hover - { 0, 1, 1 } <- primary button pressed - { 1, 1, 1 } <- touch-down - { 1, 1, 1 } <- still touch, scribble on the screen - { 0, 1, 1 } <- liftoff - { 0, 0, 0 } <- leaves - """ - - uhdev =3D self.uhdev - evdev =3D uhdev.get_evdev() - - p =3D Pen(50, 60) - p.inrange =3D True - events =3D self.post(uhdev, p) - assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1) in= events - assert evdev.value[libevdev.EV_ABS.ABS_X] =3D=3D 50 - assert evdev.value[libevdev.EV_ABS.ABS_Y] =3D=3D 60 - assert not evdev.value[libevdev.EV_KEY.BTN_STYLUS] - - p.barrelswitch =3D True - events =3D self.post(uhdev, p) - assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 1) in e= vents - - p.tipswitch =3D True - events =3D self.post(uhdev, p) - assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 1) in ev= ents - assert evdev.value[libevdev.EV_KEY.BTN_STYLUS] - - p.x +=3D 1 - p.y -=3D 1 - events =3D self.post(uhdev, p) - assert len(events) =3D=3D 3 # X, Y, SYN - assert libevdev.InputEvent(libevdev.EV_ABS.ABS_X, 51) in events - assert libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, 59) in events - - p.tipswitch =3D False - events =3D self.post(uhdev, p) - assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 0) in ev= ents - - p.barrelswitch =3D False - p.inrange =3D False - events =3D self.post(uhdev, p) - assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 0) in= events - assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 0) in e= vents - =20 class GXTP_pen(PenDigitizer): def event(self, pen): --=20 2.41.0 From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24698C46CA0 for ; Wed, 29 Nov 2023 15:56:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343929AbjK2P0H (ORCPT ); Wed, 29 Nov 2023 10:26:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44960 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235045AbjK2PZk (ORCPT ); Wed, 29 Nov 2023 10:25:40 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A1921BC6 for ; Wed, 29 Nov 2023 07:25:23 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 628B6C433C9; Wed, 29 Nov 2023 15:25:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271522; bh=w/995xxVqtTO8u3lC0LbwRgYuG2cz3TbNhfloMXAPlw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=CyskxjdQbab85B6WOL09u/AiVOaGlrIRQv8Q45u21Mg19mAm1UEKoiAqwYnfwclgv ZhbnuZEx5eHH9wAxv7Kn1ao3xymaIpF+ALVTlrf7h/4CRt1eq402hFp+AeboN5HPww IoN8Xn1GrnGwgKMLa9y6ln4bfFkZEDraF2qvtE7dkkVXhk/5uIBfDuQiIYtw7SstoG 1xTlEVJiHH0Wdw7dKrYXBmqFsIGw8k7wbScJSnFYqJP0P93ZBV/Ae5Mtaqjf4r+VNY aZtqaiPPnBWwcNRdivx+CWE+e3myRPuYNt2YDnGt7y9tsIpM4KUbKhzL+xbeCXYE2Z 3iGgAmfBrEUjA== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:36 +0100 Subject: [PATCH 11/12] selftests/hid: tablets: add a secondary barrel switch test MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-11-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=4576; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=w/995xxVqtTO8u3lC0LbwRgYuG2cz3TbNhfloMXAPlw=; b=ucW8VetRL0kO5xtEuqwr+BNOFlcTIG0bV37zbqf9YqTWowmFybNeamE/JypnOBJBzhknjY5sg YmR5vZ+H+JpA39N5Q3GwldF5BNuty5+5TlrTd4/5LNH2EK2hVl26QgG X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some tablets report 2 barrel switches. We better test those too. Use the same transistions description from the primary button tests. Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/tests/test_tablet.py | 67 ++++++++++++++++++++= ++++ 1 file changed, 67 insertions(+) diff --git a/tools/testing/selftests/hid/tests/test_tablet.py b/tools/testi= ng/selftests/hid/tests/test_tablet.py index 440a87170db1..f24cf2e168a4 100644 --- a/tools/testing/selftests/hid/tests/test_tablet.py +++ b/tools/testing/selftests/hid/tests/test_tablet.py @@ -351,6 +351,56 @@ class PenState(Enum): ), } =20 + @staticmethod + def legal_transitions_with_secondary_button() -> Dict[str, Tuple["PenS= tate", ...]]: + """We revisit the Windows Pen Implementation state machine: + we now have a secondary button. + Note: we don't looks for 2 buttons interactions. + """ + return { + "hover-button": (PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON,), + "hover-button -> out-of-range": ( + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + PenState.PEN_IS_OUT_OF_RANGE, + ), + "in-range -> button-press": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + ), + "in-range -> button-press -> button-release": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_RANGE, + ), + "in-range -> touch -> button-press -> button-release": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_CONTACT, + ), + "in-range -> touch -> button-press -> release -> button-releas= e": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_RANGE, + ), + "in-range -> button-press -> touch -> release -> button-releas= e": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_RANGE, + ), + "in-range -> button-press -> touch -> button-release -> releas= e": ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_RANGE, + ), + } + @staticmethod def tolerated_transitions() -> Dict[str, Tuple["PenState", ...]]: """This is not adhering to the Windows Pen Implementation state ma= chine @@ -429,6 +479,7 @@ class Pen(object): self.width =3D 10 self.height =3D 10 self.barrelswitch =3D False + self.secondarybarrelswitch =3D False self.invert =3D False self.eraser =3D False self.xtilt =3D 1 @@ -721,6 +772,22 @@ class BaseTest: """Rework the transition state machine by adding the primary b= utton.""" self._test_states(state_list, scribble) =20 + @pytest.mark.skip_if_uhdev( + lambda uhdev: "Secondary Barrel Switch" not in uhdev.fields, + "Device not compatible, missing Secondary Barrel Switch usage", + ) + @pytest.mark.parametrize("scribble", [True, False], ids=3D["scribb= le", "static"]) + @pytest.mark.parametrize( + "state_list", + [ + pytest.param(v, id=3Dk) + for k, v in PenState.legal_transitions_with_secondary_butt= on().items() + ], + ) + def test_valid_secondary_button_pen_states(self, state_list, scrib= ble): + """Rework the transition state machine by adding the secondary= button.""" + self._test_states(state_list, scribble) + @pytest.mark.skip_if_uhdev( lambda uhdev: "Invert" not in uhdev.fields, "Device not compatible, missing Invert usage", --=20 2.41.0 From nobody Wed Dec 17 05:55:52 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3D1DC10DAA for ; Wed, 29 Nov 2023 15:26:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344063AbjK2P0L (ORCPT ); Wed, 29 Nov 2023 10:26:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45866 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235072AbjK2PZm (ORCPT ); Wed, 29 Nov 2023 10:25:42 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5CF1C10EA for ; Wed, 29 Nov 2023 07:25:25 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 52208C433CC; Wed, 29 Nov 2023 15:25:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701271524; bh=atlZM4BJ8KQy+D392AjQoHShz//qiSp1cvnKJCX3Ivs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ed7X4MpL7h2Q0Nb/a0ndUZr30juQivEfGEe6E21vXmMTPGZ2xplKy4MaLCYkCxZU+ gnH35MT9kzRGFlDeWXhU2/CVsR4nk5Z4ck4wmy6gLw/oOs9ot6Q1K9BtjOZCd9onzd X/ohJXRAH6CZ8GfmWJnJpxXRq1LWaxTwVsNtamisj/dGW9ueqEBoqQqtdKBVZA2TrF xZsUbZAdKs3uYvkg9uvsIDPnSZHBrm+8i03t+HSMxRxv5yN5kVy2jy+rUBesHG9TzZ uEG3GJEmJo7urvpgAUzWJd5f+dg494BQ7fAwKe+gaG0EEpgHh6vO8NjfK0xGbVoF9y A1RQSbr7fdKVw== From: Benjamin Tissoires Date: Wed, 29 Nov 2023 16:24:37 +0100 Subject: [PATCH 12/12] selftests/hid: tablets: be stricter for some transitions MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20231129-wip-selftests-v1-12-ba15a1fe1b0d@kernel.org> References: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> In-Reply-To: <20231129-wip-selftests-v1-0-ba15a1fe1b0d@kernel.org> To: Jiri Kosina , Benjamin Tissoires , Shuah Khan , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1701271499; l=11244; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=atlZM4BJ8KQy+D392AjQoHShz//qiSp1cvnKJCX3Ivs=; b=fU6Sr1TqdI77cJF2Qb3FLZAa85LpecFESZGpPsUjHNBON0dpLDRrEuBbVN+unTfuN8vAUY9a/ kxSicQAgrhGBSQtF+XeAGGGd1zoz2UgjRXX/FCy6I9ZCMg2vcK3nbQY X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org To accommodate for legacy devices, we rely on the last state of a transition to be valid: for example when we test PEN_IS_OUT_OF_RANGE to PEN_IS_IN_CONTACT, any "normal" device that reports an InRange bit would insert a PEN_IS_IN_RANGE state between the 2. This is of course valid, but this solution prevents to detect false releases emitted by some firmware: when pressing an "eraser mode" button, they might send an extra PEN_IS_OUT_OF_RANGE that we may want to filter. So define 2 sets of transitions: one that is the ideal behavior, and one that is OK, it won't break user space, but we have serious doubts if we are doing the right thing. And depending on the test, either ask only for valid transitions, or tolerate weird ones. Signed-off-by: Benjamin Tissoires Reviewed-by: Peter Hutterer --- tools/testing/selftests/hid/tests/test_tablet.py | 122 +++++++++++++++++++= ---- 1 file changed, 104 insertions(+), 18 deletions(-) diff --git a/tools/testing/selftests/hid/tests/test_tablet.py b/tools/testi= ng/selftests/hid/tests/test_tablet.py index f24cf2e168a4..625dd9dcb935 100644 --- a/tools/testing/selftests/hid/tests/test_tablet.py +++ b/tools/testing/selftests/hid/tests/test_tablet.py @@ -109,7 +109,7 @@ class PenState(Enum): =20 return cls((touch, tool, button)) =20 - def apply(self, events) -> "PenState": + def apply(self, events, strict) -> "PenState": if libevdev.EV_SYN.SYN_REPORT in events: raise ValueError("EV_SYN is in the event sequence") touch =3D self.touch @@ -148,13 +148,97 @@ class PenState(Enum): button =3D None =20 new_state =3D PenState((touch, tool, button)) - assert ( - new_state in self.valid_transitions() - ), f"moving from {self} to {new_state} is forbidden" + if strict: + assert ( + new_state in self.valid_transitions() + ), f"moving from {self} to {new_state} is forbidden" + else: + assert ( + new_state in self.historical_tolerated_transitions() + ), f"moving from {self} to {new_state} is forbidden" =20 return new_state =20 def valid_transitions(self) -> Tuple["PenState", ...]: + """Following the state machine in the URL above. + + Note that those transitions are from the evdev point of view, not = HID""" + if self =3D=3D PenState.PEN_IS_OUT_OF_RANGE: + return ( + PenState.PEN_IS_OUT_OF_RANGE, + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, + PenState.PEN_IS_ERASING, + ) + + if self =3D=3D PenState.PEN_IS_IN_RANGE: + return ( + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + PenState.PEN_IS_OUT_OF_RANGE, + PenState.PEN_IS_IN_CONTACT, + ) + + if self =3D=3D PenState.PEN_IS_IN_CONTACT: + return ( + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_RANGE, + ) + + if self =3D=3D PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT: + return ( + PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, + PenState.PEN_IS_OUT_OF_RANGE, + PenState.PEN_IS_ERASING, + ) + + if self =3D=3D PenState.PEN_IS_ERASING: + return ( + PenState.PEN_IS_ERASING, + PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, + ) + + if self =3D=3D PenState.PEN_IS_IN_RANGE_WITH_BUTTON: + return ( + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_OUT_OF_RANGE, + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + ) + + if self =3D=3D PenState.PEN_IS_IN_CONTACT_WITH_BUTTON: + return ( + PenState.PEN_IS_IN_CONTACT_WITH_BUTTON, + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_RANGE_WITH_BUTTON, + ) + + if self =3D=3D PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON: + return ( + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_RANGE, + PenState.PEN_IS_OUT_OF_RANGE, + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, + ) + + if self =3D=3D PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON: + return ( + PenState.PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON, + PenState.PEN_IS_IN_CONTACT, + PenState.PEN_IS_IN_RANGE_WITH_SECOND_BUTTON, + ) + + return tuple() + + def historical_tolerated_transitions(self) -> Tuple["PenState", ...]: """Following the state machine in the URL above, with a couple of = addition for skipping the in-range state, due to historical reasons. =20 @@ -678,10 +762,12 @@ class BaseTest: self.debug_reports(r, uhdev, events) return events =20 - def validate_transitions(self, from_state, pen, evdev, events): + def validate_transitions(self, from_state, pen, evdev, events, all= ow_intermediate_states): # check that the final state is correct pen.assert_expected_input_events(evdev) =20 + state =3D from_state + # check that the transitions are valid sync_events =3D [] while libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT) in event= s: @@ -691,12 +777,12 @@ class BaseTest: events =3D events[idx + 1 :] =20 # now check for a valid transition - from_state =3D from_state.apply(sync_events) + state =3D state.apply(sync_events, not allow_intermediate_= states) =20 if events: - from_state =3D from_state.apply(sync_events) + state =3D state.apply(sync_events, not allow_intermediate_= states) =20 - def _test_states(self, state_list, scribble): + def _test_states(self, state_list, scribble, allow_intermediate_st= ates): """Internal method to test against a list of transition between states. state_list is a list of PenState objects @@ -711,7 +797,7 @@ class BaseTest: p =3D Pen(50, 60) uhdev.move_to(p, PenState.PEN_IS_OUT_OF_RANGE) events =3D self.post(uhdev, p) - self.validate_transitions(cur_state, p, evdev, events) + self.validate_transitions(cur_state, p, evdev, events, allow_i= ntermediate_states) =20 cur_state =3D p.current_state =20 @@ -720,14 +806,14 @@ class BaseTest: p.x +=3D 1 p.y -=3D 1 events =3D self.post(uhdev, p) - self.validate_transitions(cur_state, p, evdev, events) + self.validate_transitions(cur_state, p, evdev, events,= allow_intermediate_states) assert len(events) >=3D 3 # X, Y, SYN uhdev.move_to(p, state) if scribble and state !=3D PenState.PEN_IS_OUT_OF_RANGE: p.x +=3D 1 p.y -=3D 1 events =3D self.post(uhdev, p) - self.validate_transitions(cur_state, p, evdev, events) + self.validate_transitions(cur_state, p, evdev, events, all= ow_intermediate_states) cur_state =3D p.current_state =20 @pytest.mark.parametrize("scribble", [True, False], ids=3D["scribb= le", "static"]) @@ -740,7 +826,7 @@ class BaseTest: we don't have Invert nor Erase bits, so just move in/out-of-ra= nge or proximity. https://docs.microsoft.com/en-us/windows-hardware/design/compo= nent-guidelines/windows-pen-states """ - self._test_states(state_list, scribble) + self._test_states(state_list, scribble, False) =20 @pytest.mark.parametrize("scribble", [True, False], ids=3D["scribb= le", "static"]) @pytest.mark.parametrize( @@ -754,7 +840,7 @@ class BaseTest: """This is not adhering to the Windows Pen Implementation stat= e machine but we should expect the kernel to behave properly, mostly for= historical reasons.""" - self._test_states(state_list, scribble) + self._test_states(state_list, scribble, True) =20 @pytest.mark.skip_if_uhdev( lambda uhdev: "Barrel Switch" not in uhdev.fields, @@ -770,7 +856,7 @@ class BaseTest: ) def test_valid_primary_button_pen_states(self, state_list, scribbl= e): """Rework the transition state machine by adding the primary b= utton.""" - self._test_states(state_list, scribble) + self._test_states(state_list, scribble, False) =20 @pytest.mark.skip_if_uhdev( lambda uhdev: "Secondary Barrel Switch" not in uhdev.fields, @@ -786,7 +872,7 @@ class BaseTest: ) def test_valid_secondary_button_pen_states(self, state_list, scrib= ble): """Rework the transition state machine by adding the secondary= button.""" - self._test_states(state_list, scribble) + self._test_states(state_list, scribble, False) =20 @pytest.mark.skip_if_uhdev( lambda uhdev: "Invert" not in uhdev.fields, @@ -806,7 +892,7 @@ class BaseTest: to erase. https://docs.microsoft.com/en-us/windows-hardware/design/compo= nent-guidelines/windows-pen-states """ - self._test_states(state_list, scribble) + self._test_states(state_list, scribble, False) =20 @pytest.mark.skip_if_uhdev( lambda uhdev: "Invert" not in uhdev.fields, @@ -826,7 +912,7 @@ class BaseTest: to erase. https://docs.microsoft.com/en-us/windows-hardware/design/compo= nent-guidelines/windows-pen-states """ - self._test_states(state_list, scribble) + self._test_states(state_list, scribble, True) =20 @pytest.mark.skip_if_uhdev( lambda uhdev: "Invert" not in uhdev.fields, @@ -843,7 +929,7 @@ class BaseTest: For example, a pen that has the eraser button might wobble bet= ween touching and erasing if the tablet doesn't enforce the Windows state machine.""" - self._test_states(state_list, scribble) + self._test_states(state_list, scribble, True) =20 =20 class GXTP_pen(PenDigitizer): --=20 2.41.0