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
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index d7aea4e..a2582a5 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -2184,6 +2184,15 @@
     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.