SurfaceControl: Add setDropInputMode api

Introduces an API to drop input events on this SurfaceControl. This
policy will be inherited by its children. The caller must hold the
ACCESS_SURFACE_FLINGER permission.

Options include:
ALL: SurfaceControl and its children will not receive any
input regardless of whether it has a valid input channel.
OBSCURED: SurfaceControl and its children will not
receive any input if the layer is obscured, cropped by its parent or
translucent.

These policies are used to enable features that allow for a less trusted
interaction model between apps. See the bug for more details.

Test: atest libgui_test InputDispatcherDropInputFeatureTest
Bug:197364677

Merged-In: I443741d5ab51a45d37fb865f11c433c436d96c1e
Change-Id: I443741d5ab51a45d37fb865f11c433c436d96c1e
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 326da3a..8c250a4 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -55,6 +55,7 @@
 filegroup {
     name: "guiconstants_aidl",
     srcs: [
+        "android/**/DropInputMode.aidl",
         "android/**/TouchOcclusionMode.aidl",
     ],
 }
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 8a7a871..54735fa 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -70,7 +70,8 @@
         isTrustedOverlay(false),
         bufferCrop(Rect::INVALID_RECT),
         destinationFrame(Rect::INVALID_RECT),
-        releaseBufferListener(nullptr) {
+        releaseBufferListener(nullptr),
+        dropInputMode(gui::DropInputMode::NONE) {
     matrix.dsdx = matrix.dtdy = 1.0f;
     matrix.dsdy = matrix.dtdx = 0.0f;
     hdrMetadata.validTypes = 0;
@@ -175,6 +176,7 @@
     SAFE_PARCEL(output.writeBool, isTrustedOverlay);
 
     SAFE_PARCEL(output.writeStrongBinder, releaseBufferEndpoint);
+    SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(dropInputMode));
     return NO_ERROR;
 }
 
@@ -305,6 +307,10 @@
     SAFE_PARCEL(input.readBool, &isTrustedOverlay);
 
     SAFE_PARCEL(input.readNullableStrongBinder, &releaseBufferEndpoint);
+
+    uint32_t mode;
+    SAFE_PARCEL(input.readUint32, &mode);
+    dropInputMode = static_cast<gui::DropInputMode>(mode);
     return NO_ERROR;
 }
 
@@ -563,6 +569,10 @@
         what |= eDestinationFrameChanged;
         destinationFrame = other.destinationFrame;
     }
+    if (other.what & eDropInputModeChanged) {
+        what |= eDropInputModeChanged;
+        dropInputMode = other.dropInputMode;
+    }
     if ((other.what & what) != other.what) {
         ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
               "other.what=0x%" PRIu64 " what=0x%" PRIu64,
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index a2037ac..843e2ff 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1739,6 +1739,21 @@
     return *this;
 }
 
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDropInputMode(
+        const sp<SurfaceControl>& sc, gui::DropInputMode mode) {
+    layer_state_t* s = getLayerState(sc);
+    if (!s) {
+        mStatus = BAD_INDEX;
+        return *this;
+    }
+
+    s->what |= layer_state_t::eDropInputModeChanged;
+    s->dropInputMode = mode;
+
+    registerSurfaceControlForCallback(sc);
+    return *this;
+}
+
 // ---------------------------------------------------------------------------
 
 DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) {
diff --git a/libs/gui/android/gui/DropInputMode.aidl b/libs/gui/android/gui/DropInputMode.aidl
new file mode 100644
index 0000000..2b31744
--- /dev/null
+++ b/libs/gui/android/gui/DropInputMode.aidl
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2021, 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.gui;
+
+
+/**
+  * Input event drop modes: Input event drop options for windows and its children.
+  *
+  * @hide
+  */
+@Backing(type="int")
+enum DropInputMode {
+    /**
+      * Default mode, input events are sent to the target as usual.
+      */
+    NONE,
+
+    /**
+      * Window and its children will not receive any input even if it has a valid input channel.
+      * Touches and keys will be dropped. If a window is focused, it will remain focused but will
+      * not receive any keys. If the window has a touchable region and is the target of an input
+      * event, the event will be dropped and will not go to the window behind. ref: b/197296414
+      */
+    ALL,
+
+    /**
+      * Similar to DROP but input events are only dropped if the window is considered to be
+      * obscured. ref: b/197364677
+      */
+    OBSCURED
+}
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 8dc8b9a..03e4aac 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -26,6 +26,7 @@
 #include <gui/ITransactionCompletedListener.h>
 #include <math/mat4.h>
 
+#include <android/gui/DropInputMode.h>
 #include <android/gui/FocusRequest.h>
 
 #include <gui/ISurfaceComposer.h>
@@ -117,6 +118,7 @@
         eAutoRefreshChanged = 0x1000'00000000,
         eStretchChanged = 0x2000'00000000,
         eTrustedOverlayChanged = 0x4000'00000000,
+        eDropInputModeChanged = 0x8000'00000000,
     };
 
     layer_state_t();
@@ -247,6 +249,9 @@
     // releaseCallbackId and release fence to all listeners so we store which listener the setBuffer
     // was called with.
     sp<IBinder> releaseBufferEndpoint;
+
+    // Force inputflinger to drop all input events for the layer and its children.
+    gui::DropInputMode dropInputMode;
 };
 
 struct ComposerState {
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 0f8a32b..4ff2aa0 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -562,6 +562,7 @@
         Transaction& setBufferCrop(const sp<SurfaceControl>& sc, const Rect& bufferCrop);
         Transaction& setDestinationFrame(const sp<SurfaceControl>& sc,
                                          const Rect& destinationFrame);
+        Transaction& setDropInputMode(const sp<SurfaceControl>& sc, gui::DropInputMode mode);
 
         status_t setDisplaySurface(const sp<IBinder>& token,
                 const sp<IGraphicBufferProducer>& bufferProducer);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 638bb9b..e097745 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -135,6 +135,7 @@
     mDrawingState.postTime = -1;
     mDrawingState.destinationFrame.makeInvalid();
     mDrawingState.isTrustedOverlay = false;
+    mDrawingState.dropInputMode = gui::DropInputMode::NONE;
 
     if (args.flags & ISurfaceComposerClient::eNoColorFill) {
         // Set an invalid color so there is no color fill.
@@ -2576,6 +2577,14 @@
     return handle->owner;
 }
 
+bool Layer::setDropInputMode(gui::DropInputMode mode) {
+    if (mDrawingState.dropInputMode == mode) {
+        return false;
+    }
+    mDrawingState.dropInputMode = mode;
+    return true;
+}
+
 // ---------------------------------------------------------------------------
 
 std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 470103c..e4276f5 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -17,6 +17,7 @@
 
 #pragma once
 
+#include <android/gui/DropInputMode.h>
 #include <compositionengine/LayerFE.h>
 #include <gui/BufferQueue.h>
 #include <gui/ISurfaceComposerClient.h>
@@ -282,6 +283,8 @@
         Rect destinationFrame;
 
         sp<IBinder> releaseBufferEndpoint;
+
+        gui::DropInputMode dropInputMode;
     };
 
     /*
@@ -447,6 +450,8 @@
     virtual bool setFrameRateSelectionPriority(int32_t priority);
     virtual bool setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHint);
     virtual void setAutoRefresh(bool /* autoRefresh */) {}
+    bool setDropInputMode(gui::DropInputMode);
+
     //  If the variable is not set on the layer, it traverses up the tree to inherit the frame
     //  rate priority from its parent.
     virtual int32_t getFrameRateSelectionPriority() const;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index aab8331..786d2bb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4149,6 +4149,16 @@
             flags |= eTraversalNeeded;
         }
     }
+    if (what & layer_state_t::eDropInputModeChanged) {
+        if (privileged) {
+            if (layer->setDropInputMode(s.dropInputMode)) {
+                flags |= eTraversalNeeded;
+                mInputInfoChanged = true;
+            }
+        } else {
+            ALOGE("Attempt to update InputPolicyFlags without permission ACCESS_SURFACE_FLINGER");
+        }
+    }
     // This has to happen after we reparent children because when we reparent to null we remove
     // child layers from current state and remove its relative z. If the children are reparented in
     // the same transaction, then we have to make sure we reparent the children first so we do not