Since phoc 0.39.0 it is possible to configure which keys unidle your phone (which results in unblanking the screen).

The current default is that all keys unblank which is usually fine for e.g. laptops but not the desired result for phones and tablets where this depends on the position and function of keys. Volume keys and other exposed keys usually shouldn’t unblank - maybe with the exception of some Home buttons on devices that have those.

hwdb bits displayed in a terminal

The information to configure this can be provided to phoc via udev properties which it reads via libinput. In order to ease configuration of these properties gmobile as of 0.2.0 provides udev rules that allow to add these properties via systemd’s hwdb. (Users of non systemd devices please read on, you can still make this work).

In the following we show how to add the information for a OnePlus 6T so that only the power key unblanks. We use that particular phone as example as (at the time of writing) it doesn’t yet have out of the box configuration in gmobile) yet. This phone has three physical buttons: a power button which should unblank and volume up/down which shouldn’t unblank (the alert slider doesn’t generate any key events over here yet).

Let’s add the necessary entries for this:

Gathering the data Link to heading

We first need to figure out the name of the input device that emits the volume button events and the input event codes. For that we use the libinput command. On Debian based systems you’ll find that in the libinput-tools package:

sudo apt install libinput-tools

With that installed let’s run libinput debug-events. The output right after startup should look similar to this:

-event2   DEVICE_ADDED            Hall effect sensor                seat0 default group1  cap:S
-event3   DEVICE_ADDED            Volume keys                       seat0 default group1  cap:k
-event5   DEVICE_ADDED            Synaptics S3706B                  seat0 default group2  cap:t  size 154x69mm ntouches 10 calib
-event0   DEVICE_ADDED            pm8941_pwrkey                     seat0 default group3  cap:k
-event6   DEVICE_ADDED            OnePlus 6T Headset Jack           seat0 default group4  cap:k

The actual device names in the 3rd column and the event devices in the 1st column vary by device. Now press volume up and volume down. You should see something like:

-event3   KEYBOARD_KEY            +4294967.294s	KEY_VOLUMEUP (115) pressed
 event3   KEYBOARD_KEY            +0.191s	KEY_VOLUMEUP (115) released
 event3   KEYBOARD_KEY            +5.053s	KEY_VOLUMEDOWN (114) pressed
 event3   KEYBOARD_KEY            +5.238s	KEY_VOLUMEDOWN (114) released

So in our case we see that event3 is the device generating events on volume button press and that the volume keys have the input event codes 114 and 115. Let’s write that down.

Equipped with that. let’s look at the udev properties of the volume key input device:

sudo udevadm info -p /sys/class/input/event3

Which should print

P: /devices/platform/gpio-keys/input/input3/event3
M: event3
R: 3
U: input
D: c 13:67
N: input/event3
L: 0
S: input/by-path/platform-gpio-keys-event
E: DEVPATH=/devices/platform/gpio-keys/input/input3/event3
E: SUBSYSTEM=input
E: DEVNAME=/dev/input/event3
E: MAJOR=13
E: MINOR=67
E: USEC_INITIALIZED=9134284
E: ID_INPUT=1
E: ID_INPUT_KEY=1
E: ID_PATH=platform-gpio-keys
E: ID_PATH_TAG=platform-gpio-keys
E: LIBINPUT_DEVICE_GROUP=19/1/1:gpio-keys
E: DEVLINKS=/dev/input/by-path/platform-gpio-keys-event
E: TAGS=:power-switch:
E: CURRENT_TAGS=:power-switch:

If there would already be configuration via gmobile we’d see entries like

E: GM_WAKEUP_KEY_<id>=<0|1>

but nothing like this is there yet.

Building the hwdb entry Link to heading

We can now look at building the hwdb entry which takes the form of a match pattern to identify a particular keyboard controller on a particular phone and associated key-value pairs that describe what to do with individual keys on that controller. The exact form of the match pattern is defined by the udev rule shipped in gmobile:

gmobile:name:<devicename>:dt:<dt-compatible>

<devicename> is the name of our volume button device and <dt-compatible> is the first part of the device tree compatible (basically identifying the model of the phone).

We already got the sysfs path of the volume button device, we can now get the <devicename> bit too via:

cat /sys/class/input/event3/device/name

Which on the OnePlus 6T shows

Volume keys

The <dt-compatible> bit can also be found in sysfs:

cat /sys/firmware/devicetree/base/compatible | tr '\0' '\n'

gives the output:

oneplus,fajita
qcom,sdm845

This results in the match pattern gmobile:name:Volume keys:dt:oneplus,fajita*. Since we also already have the input event codes 114 and 115 for the volume keys so we can already build the hwdb entry:

gmobile:name:Volume keys:dt:oneplus,fajita*
 GM_WAKEUP_KEY_114=0
 GM_WAKEUP_KEY_115=0

where GM_WAKEUP_KEY_<keyid>=0 are the key-value pairs that get turned into udev properties. If your device has more keys and you don’t want to change their behaviour then there’s no need to list them (e.g. we don’t change anything for the device’s power button). If you want to ignore all keys of a device you can use GM_WAKEUP_KEY_DEFAULT=0 instead of listing individual keys.

For testing let’s put that information where systemd can find it:

cat <<EOF |sudo tee /etc/udev/hwdb.d/99-gmobile-test.hwdb
gmobile:name:Volume keys:dt:oneplus,fajita*
 GM_WAKEUP_KEY_114=0
 GM_WAKEUP_KEY_115=0
EOF

We then update the hwdb cache:

sudo systemd-hwdb update

which generates a /etc/udev/hwdb.bin. You can check the file’s timestamp to be sure that happened.

We could reboot now to have udev pick this up but just refreshing the udev properties is quicker:

sudo udevadm trigger /sys/class/input/event3

If everything worked out right we should now see additional properties that can be used by phoc:

sudo udevadm info -p /sys/class/input/event3 | grep 'GM_'

which should now print:

E: GM_WAKEUP_KEY_114=0
E: GM_WAKEUP_KEY_115=0

If you now restart your phosh session and blank the screen, pressing the volume keys will no longer unblank (it will still allow you to tweak the volume so you don’t need to unlock the device in order to make your music a bit louder).

If you figured out the above for your device please submit the hwdb entry to gmobile upstream so others benefit too. Note that the format of the hwdb entries may change in the future. Submitting your hwdb entries upstream makes sure we can fix them up as well.

What if you’re not happy what keys get ignored via the rules shipped in gmobile (e.g. if the power button on your device is somewhat broken and you want another button to unblank too)? In that case you can use GM_WAKEUP_KEY_115=1 to override what gmobile sets by default.

See the gmobile.udev manpage for some more details.

Non-systemd systems Link to heading

On devices that don’t use systemd but e.g. eudev and which might not support all of the needed matching rules (see e.g. this issue in postmarketOS) you can still make use of that functionality by writing a udev rule directly instead of going via hwdb.

Here’s an example that just matches on the ID_PATH property of the event3 device we used in the above example and sets GM_WAKEUP_KEY_:

cat <<EOF |sudo tee /etc/udev/rules.d/99-non-hwdb.rules
ACTION=="remove", GOTO="non_hwdb_end"
KERNEL!="event*", GOTO="non_hwdb_end"

KERNELS=="input*", ENV{ID_PATH}=="platform-gpio-keys", ENV{GM_WAKEUP_KEY_114}="0", ENV{GM_WAKEUP_KEY_115}="0"

LABEL="non_hwdb_end"
EOF

After putting that into place we can reload the rules, trigger the events and check the result:

sudo udevadm control -R
sudo udevadm trigger /sys/class/input/event3
sudo udevadm info -p /sys/class/input/event3 | grep 'GM_'

which should give the same result as in the hwdb case:

E: GM_WAKEUP_KEY_114=0
E: GM_WAKEUP_KEY_115=0

Closing Link to heading

In the above we see how one can tell phoc which keys shouldn’t unblank the screen. In order to get better defaults we want to make the list of keys that do this match the keys that wake up the device from suspend. A patch to make that information available to user space for the very common gpio-keys driver has already been submitted.

With that we can import a default list of keys. The hwdb way to configure things will still remain useful as it allows us to override these defaults and to provide values for devices using other drivers (until the kernel catches up there eventually too).

We’ve put the logic for this into gmobile rather than phoc itself as this makes it easily reusable by other projects / Wayland compositors (even when they don’t use other gmobile features).

Have fun configuring the hardware keys of your device. Let us know if it worked at https://fosstodon.org/@phosh/112507238678527753 .

Thanks to Sam Day for the phoc side implementation, Lennard Poettering, Peter Hutterer and Hans de Goede for their input on the hwdb and udev bits and Arun Mani J for proofreading.