Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 653d2e0c authored by Bernardo Rufino's avatar Bernardo Rufino
Browse files

Exempt (0-opacity & NOT_TOUCHABLE) windows from occlusion detection

If there is a FLAG_NOT_TOUCHABLE window with 0-opacity in the touch
path and the touch-consuming app uses the filter touches API, the touch
will be blocked and the user will likely be confused since they can't
actually see the obscuring window. This CL makes it so that the touch
won't be blocked.

This also helps reduce app-compat problems arising from block untrusted
touches feature (including b/166617888).

From a security standpoint, we're only going to exempt the 0 special
float value, not even the minimum representable positive float value
will be exempt, so apps can't abuse this by stacking multiple
near-transparent windows to evade occlusion detection. In practice apps
can already achieve the same user-facing effect today by toggling the
visibility of the window, so this is not a new attack surface.

We are also checking for the presence of FLAG_NOT_TOUCHABLE due to the
FLAG_WINDOW_IS_PARTIALLY_OBSCURED code-path (since for a window to cause
the touch to be flagged with FLAG_WINDOW_IS_OBSCURED it has to be in the
touch path, which naturally implies FLAG_NOT_TOUCHABLE). Apps that rely
on FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about any
potential touch-consuming windows, since those affect the behavior of
the user interaction.

Test: atest WindowUntrustedTouchTest WindowInputTests inputflinger_tests
      inputflinger_benchmarks libinput_tests libgui_test
Bug: 166617888
Bug: 158002302
Change-Id: I44ad362b3b2519bf87bd1667a6fa2132127f3857
parent fac95177
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -2184,6 +2184,15 @@ static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
    auto otherInfo = otherHandle->getInfo();
    if (!otherInfo->visible) {
        return false;
    } else if (otherInfo->alpha == 0 &&
               otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
        // Those act as if they were invisible, so we don't need to flag them.
        // We do want to potentially flag touchable windows even if they have 0
        // opacity, since they can consume touches and alter the effects of the
        // user interaction (eg. apps that rely on
        // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
        // windows), hence we also check for FLAG_NOT_TOUCHABLE.
        return false;
    } else if (info->ownerUid == otherInfo->ownerUid) {
        // If ownerUid is the same we don't generate occlusion events as there
        // is no security boundary within an uid.