Block untrusted touches in InputDispatcher

With topic CL InputDispatcher now has the effect of each window for
cross-UID touch occlusion rules: ALLOW, USE_OPACITY or BLOCK_UNTRUSTED.
Check topic CL for exact meaning of each. USE_OPACITY is only used by
SAWs for now.

In this CL, InputDispatcher make use of that information for the stack
of windows above the touch-consuming window to block a touch or not.

The summary of the rules are:
* If there is any visible untrusted window from a different UID (than
the touch-consuming window UID) that has state BLOCK_UNTRUSTED, the
touch is blocked.
* Else, if there is any visible untrusted window from a different UID
that has state USE_OPACITY, we compute the composed obscuring opacity
by each stack of USE_OPACITY windows per UID of occluding window.
We take maximum of those and compare with secure setting
"maximum_obscuring_opacity_for_touch", if it's greater than the
setting the touch is blocked. This means the remaining visibility on the
touch-consuming window is not high enough to let the touch happen.
* Else we don't block the touch.

More details on go/cross-uid-touches. This doesn't interfere with
existing flags FLAG_WINDOW_IS_OBSCURED and
FLAG_WINDOW_IS_PARTIALLY_OBSCURED.

To compute the opacity we also propagate the alpha of each window from
SurfaceFlinger to InputDispatcher.

Test: atest WindowUntrustedTouchTest
Test: atest inputflinger_tests inputflinger_benchmarks libinput_tests
Test: go/try-cross-uid-touches for manual testing
Bug: 158002302
Change-Id: I673d7a5f16b19952311e8cb44a48af4349a4bd40
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 8f575a8..b442700 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -18,6 +18,8 @@
     name: "inputconstants_aidl",
     srcs: [
         "android/os/IInputConstants.aidl",
+        "android/os/TouchOcclusionMode.aidl",
+        "android/os/BlockUntrustedTouchesMode.aidl",
     ],
 }
 
@@ -71,10 +73,14 @@
                 "android/FocusRequest.aidl",
                 "android/InputApplicationInfo.aidl",
                 "android/os/IInputConstants.aidl",
+                "android/os/TouchOcclusionMode.aidl",
+                "android/os/BlockUntrustedTouchesMode.aidl",
                 "android/os/IInputFlinger.aidl",
                 "android/os/ISetInputWindowsListener.aidl",
             ],
 
+            export_shared_lib_headers: ["libbinder"],
+
             shared_libs: [
                 "libutils",
                 "libbinder",
diff --git a/libs/input/InputWindow.cpp b/libs/input/InputWindow.cpp
index 885dc9b..8546bbb 100644
--- a/libs/input/InputWindow.cpp
+++ b/libs/input/InputWindow.cpp
@@ -59,10 +59,11 @@
             info.surfaceInset == surfaceInset && info.globalScaleFactor == globalScaleFactor &&
             info.transform == transform && info.touchableRegion.hasSameRects(touchableRegion) &&
             info.visible == visible && info.trustedOverlay == trustedOverlay &&
-            info.focusable == focusable && info.hasWallpaper == hasWallpaper &&
-            info.paused == paused && info.ownerPid == ownerPid && info.ownerUid == ownerUid &&
-            info.inputFeatures == inputFeatures && info.displayId == displayId &&
-            info.portalToDisplayId == portalToDisplayId &&
+            info.focusable == focusable && info.touchOcclusionMode == touchOcclusionMode &&
+            info.hasWallpaper == hasWallpaper && info.paused == paused &&
+            info.ownerPid == ownerPid && info.ownerUid == ownerUid &&
+            info.packageName == packageName && info.inputFeatures == inputFeatures &&
+            info.displayId == displayId && info.portalToDisplayId == portalToDisplayId &&
             info.replaceTouchableRegionWithCrop == replaceTouchableRegionWithCrop &&
             info.applicationInfo == applicationInfo;
 }
@@ -91,6 +92,7 @@
         parcel->writeInt32(frameBottom) ?:
         parcel->writeInt32(surfaceInset) ?:
         parcel->writeFloat(globalScaleFactor) ?:
+        parcel->writeFloat(alpha) ?:
         parcel->writeFloat(transform.dsdx()) ?:
         parcel->writeFloat(transform.dtdx()) ?:
         parcel->writeFloat(transform.tx()) ?:
@@ -102,8 +104,10 @@
         parcel->writeBool(hasWallpaper) ?:
         parcel->writeBool(paused) ?:
         parcel->writeBool(trustedOverlay) ?:
+        parcel->writeInt32(static_cast<int32_t>(touchOcclusionMode)) ?:
         parcel->writeInt32(ownerPid) ?:
         parcel->writeInt32(ownerUid) ?:
+        parcel->writeUtf8AsUtf16(packageName) ?:
         parcel->writeInt32(inputFeatures.get()) ?:
         parcel->writeInt32(displayId) ?:
         parcel->writeInt32(portalToDisplayId) ?:
@@ -134,6 +138,7 @@
     flags = Flags<Flag>(parcel->readInt32());
     type = static_cast<Type>(parcel->readInt32());
     float dsdx, dtdx, tx, dtdy, dsdy, ty;
+    int32_t touchOcclusionModeInt;
     // clang-format off
     status = parcel->readInt32(&frameLeft) ?:
         parcel->readInt32(&frameTop) ?:
@@ -141,6 +146,7 @@
         parcel->readInt32(&frameBottom) ?:
         parcel->readInt32(&surfaceInset) ?:
         parcel->readFloat(&globalScaleFactor) ?:
+        parcel->readFloat(&alpha) ?:
         parcel->readFloat(&dsdx) ?:
         parcel->readFloat(&dtdx) ?:
         parcel->readFloat(&tx) ?:
@@ -152,14 +158,18 @@
         parcel->readBool(&hasWallpaper) ?:
         parcel->readBool(&paused) ?:
         parcel->readBool(&trustedOverlay) ?:
+        parcel->readInt32(&touchOcclusionModeInt) ?:
         parcel->readInt32(&ownerPid) ?:
-        parcel->readInt32(&ownerUid);
+        parcel->readInt32(&ownerUid) ?:
+        parcel->readUtf8FromUtf16(&packageName);
     // clang-format on
 
     if (status != OK) {
         return status;
     }
 
+    touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt);
+
     inputFeatures = Flags<Feature>(parcel->readInt32());
     status = parcel->readInt32(&displayId) ?:
         parcel->readInt32(&portalToDisplayId) ?:
diff --git a/libs/input/android/os/BlockUntrustedTouchesMode.aidl b/libs/input/android/os/BlockUntrustedTouchesMode.aidl
new file mode 100644
index 0000000..9504e99
--- /dev/null
+++ b/libs/input/android/os/BlockUntrustedTouchesMode.aidl
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+
+/**
+  * Block untrusted touches feature mode.
+  *
+  * @hide
+  */
+@Backing(type="int")
+enum BlockUntrustedTouchesMode {
+    /** Feature is off. */
+    DISABLED,
+
+    /** Untrusted touches are flagged but not blocked. */
+    PERMISSIVE,
+
+    /** Untrusted touches are blocked. */
+    BLOCK
+}
diff --git a/libs/input/android/os/TouchOcclusionMode.aidl b/libs/input/android/os/TouchOcclusionMode.aidl
new file mode 100644
index 0000000..106f159
--- /dev/null
+++ b/libs/input/android/os/TouchOcclusionMode.aidl
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+
+/**
+  * Touch occlusion modes: These modes represent how windows are taken into
+  * consideration in order to decide whether to block obscured touches or
+  * not.
+  *
+  * @hide
+  */
+@Backing(type="int")
+enum TouchOcclusionMode {
+    /**
+      * Touches that pass through this window will be blocked if they are
+      * consumed by a different UID and this window is not trusted.
+      */
+    BLOCK_UNTRUSTED,
+
+    /**
+      * The window's opacity will be taken into consideration for touch
+      * occlusion rules if the touch passes through it and the window is not
+      * trusted.
+      */
+    USE_OPACITY,
+
+    /**
+      * The window won't count for touch occlusion rules if the touch passes
+      * through it.
+      */
+    ALLOW
+}
diff --git a/libs/input/tests/InputWindow_test.cpp b/libs/input/tests/InputWindow_test.cpp
index 65a7761..c18a17f 100644
--- a/libs/input/tests/InputWindow_test.cpp
+++ b/libs/input/tests/InputWindow_test.cpp
@@ -53,13 +53,16 @@
     i.frameBottom = 19;
     i.surfaceInset = 17;
     i.globalScaleFactor = 0.3;
+    i.alpha = 0.7;
     i.transform.set({0.4, -1, 100, 0.5, 0, 40, 0, 0, 1});
     i.visible = false;
     i.focusable = false;
     i.hasWallpaper = false;
     i.paused = false;
+    i.touchOcclusionMode = TouchOcclusionMode::ALLOW;
     i.ownerPid = 19;
     i.ownerUid = 24;
+    i.packageName = "com.example.package";
     i.inputFeatures = InputWindowInfo::Feature::DISABLE_USER_ACTIVITY;
     i.displayId = 34;
     i.portalToDisplayId = 2;
@@ -86,13 +89,16 @@
     ASSERT_EQ(i.frameBottom, i2.frameBottom);
     ASSERT_EQ(i.surfaceInset, i2.surfaceInset);
     ASSERT_EQ(i.globalScaleFactor, i2.globalScaleFactor);
+    ASSERT_EQ(i.alpha, i2.alpha);
     ASSERT_EQ(i.transform, i2.transform);
     ASSERT_EQ(i.visible, i2.visible);
     ASSERT_EQ(i.focusable, i2.focusable);
     ASSERT_EQ(i.hasWallpaper, i2.hasWallpaper);
     ASSERT_EQ(i.paused, i2.paused);
+    ASSERT_EQ(i.touchOcclusionMode, i2.touchOcclusionMode);
     ASSERT_EQ(i.ownerPid, i2.ownerPid);
     ASSERT_EQ(i.ownerUid, i2.ownerUid);
+    ASSERT_EQ(i.packageName, i2.packageName);
     ASSERT_EQ(i.inputFeatures, i2.inputFeatures);
     ASSERT_EQ(i.displayId, i2.displayId);
     ASSERT_EQ(i.portalToDisplayId, i2.portalToDisplayId);