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](/posts/wakeup-keys/gmobile-hwdb.png)
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.