[systemd-devel] Bad accelerometer values cause incorrect screen rotation
Daniel Drake
drake at endlessm.com
Thu Sep 5 09:05:11 UTC 2019
Hi,
Over the years we've seen a bunch of reports of systems that
automatically rotate the display to some incorrect orientation, based
on trusting some accelerometer data values which were not interpreted
correctly. I have another affected system in hand here.
When this unfortunate situation happens, the user experience is really
terrible. Except for workarounds that involve going to the command
line, the best workaround under GNOME seems to be to physically rotate
the device into a position that causes the screen orientation to be
normal/unrotated, then while maintaining and holding the device in
that highly awkward position with one hand, try your very best to
manipulate the mouse cursor with your other hand and navigate the menu
to enable Orientation Lock.
Since the effects of this issue when it bites are so bad, and because
it seems like we aren't winning the "quirk the accelerometer" game
here, I'm wondering if it's time for us to restrict this default
setting of automatic rotation based on accelerometer data to only
situations where:
1. The product is actually designed to be usable when rotated, and
2. We have a higher degree of confidence that we're actually
interpreting the accelerometer data correctly
Why are we not winning? Why can't we fix this properly?
I think we're suffering largely through applying this auto-rotation
behaviour to all accelerometer data, from setups where previously
nobody really cared if the data was misinterpreted, or the data was
specifically interpreted for a different context (we're specifically
interested in measuring the physical orientation of the screen, but
accelerometers have other uses too).
Windows 10 (and presumably 8) does have the automatic screen rotation
feature based on accelerometer data, but it seems to apply to fewer
products. For example it does not apply automatic rotation to the
Quanta NL3 classmate nor to the HP EliteBook 840 G3, two systems that
I have in hand that both required specific engineering on Linux after
real users had already run into the horrible
automatic-incorrect-rotation described above:
https://github.com/systemd/systemd/commit/ebf482e7cdabfc1266a86ec8a5f92a964ce08afe
hp_accel: fix accelerometer orientation for EliteBook 840 (patch
posted today, no link yet)
The challenge here is a lack of standardization of how accelerometers
are installed relative to the screen, and a lack of a standard way of
accessing model-specific data that gives us this info. Without any
better options we've been trying to create and maintain our own
databases, for example systemds 60-sensor.hwdb and Linux kernel's
hp_accel.c, but that's turning out to be problematic because:
1. The databases entries are mostly created retroactively - usually,
entries are created when a tech-savvy user steps forward to share the
required data, after one or more users have already been bitten by the
issue. This is sub-standard.
2. We estimate the right way to distinguish models for different
quirks by hoping that DMI data will serve this purpose, but we also
don't know how to do that reliably, so sometimes we even apply the
wrong quirks. Two recent examples:
https://bugzilla.redhat.com/show_bug.cgi?id=1717712 (more on this case below)
hp_accel: fix accelerometer orientation for EliteBook 840 (patch
posted today, no link yet)
Bastien once made the suggestion that we could fish the model-to-quirk
mapping from the Windows drivers, but I can't find anything in the HP
driver. On HP EliteBook 840 the device is not even exposed as a sensor
under Windows and I can't find any way of accessing the data or making
it auto-rotate - maybe they don't even have such a mapping? The only
Windows application of this sensor seems to be automatic hard disk
head parking, which presumably just detects sudden movements in any
direction.
We did recently work with some Acer all-in-one PCs which had an
accelerometer which also provided working auto-rotation under windows
out of the box, while again producing the wrong and awkward behaviour
on Linux. Thanks to vendor contacts we did discover the scheme used,
and now automatically detect the accelerometer orientation on such
products.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f38ab20b749da84e3df1f8c9240ddc791b0d5983
However, we then found DSDTs with this orientation data that far
predated this patch's existence. So not a great win; our solution was
not made in timely fashion.
ACPI offers something that might help - PLD can be used to describe
the physical orientation of product components. But I don't think
we've seen any examples of this data being provided by vendors for
accelerometers.
I see the latest development of having the hwdb specify whether the
accelerometer is in the base or the display of the device. This was
implemented for dealing with a device with accelerometers in both
positions (https://github.com/hadess/iio-sensor-proxy/pull/262) -
clearly the screen rotation should only follow thy display-mounted
accelerometer in that case.
However now that iio-sensor-proxy ignores "base" accelerometers
(regardless of whether or not there's another accelerometer in the
display), that's being misused at least in this case:
https://bugzilla.redhat.com/show_bug.cgi?id=1717712
This is a HP laptop and it looked like the policy was once "we will
not accept quirks for HP machines that use the lis3lv02d device, they
should go in the hp_accel.c driver instead"
(https://github.com/systemd/systemd/commit/0d1a2be93e16aa03026f1c36e81951097e8dad2c)
but that doesn't seem to have been followed here.
Although in this case the quirk just states that the sensor is in the
base of the laptop, which now causes iio-sensor-proxy to ignore it.
But since the kernel data was wrong in the first place, the user is
now left with an accelerometer that can't be used to play neverball,
nor can be used to rotate the screen.
In the single accelerometer case, for an ordinary clamshell laptop, it
doesn't actually matter if the accelerometer is in the display or not.
Since the accelerometer measures all 3 dimensions and screen position
relative to the base is known, a mount matrix can be applied to deal
with any positioning scheme.
What if we had an ordinary clamshell laptop producing "bad" data where
the accelerometer is actually mounted behind the display (was this
even checked here?) - would a ACCEL_POSITION=base quirk still then be
accepted?
Although this fix seems somewhat technically incorrect, perhaps it has
its roots in the same things I'm trying to say here: when the bug
bites it's really quite serious, it's tricky and annoying to fix the
root cause, and why do we even care about automatic screen rotation on
standard clamshell laptops anyway - the product itself is totally
unusable when in any position other than "sitting flat on the desk" -
just try typing or using the touchpad...
How can we improve?
Ideally I think we should disable the automatic rotation on all
devices except for:
- Laptops that have detachable screens (effectively converting them
into a tablet) with the accelerometer mounted to the screen
- Convertible laptops where the screen can be physically rotated
around and folded down to sit on top of the keyboard, with the
accelerometer mounted to the screen
- All in One PCs
- Tablets
- Smartphones
By nature of not automatically rotating on ordinary clamshell laptops,
that would actually solve 100% of the cases that I've come across.
But maybe we're then left with similar "how can we detect the
mount-matrix" problems on the remaining device classes (I'm especially
unfamiliar with tablets and smartphones).
And detecting the different device classes is also not trivial. DMI
and ACPI don't offer precisely what we need here, and vendors aren't
especially consistent there anyway.
The best proposal I can think of is to disable automatic rotation on
all devices, except for systems that pass two tests:
1. The DMI chassis type is All In One or HandHeld, or the ACPI power
profile is tablet (hostnamectl already reads this - perhaps it has
some degree of reliability?), or the model is on a "this
accelerometer-equipped device can sensibly be used in different
physical orientations" hwdb whitelist
and:
2. The kernel exports a mount matrix, or there is a mount matrix in
the hwdb (the identity matrix can be used to create further whitelist
entries). If we have multiple accelerometers, require a hwdb whitelist
to determine which one is display-mounted.
Also leaving some room for a potential future UI control to override
this (and calibrate too?).
End of brainstorm... Any thoughts?
Thanks,
Daniel
More information about the systemd-devel
mailing list