Merge cherrypicks of [15975347, 15975348, 15975349, 16508592, 16508593, 16508594, 18029504] into rvc-platform-release.

Change-Id: I9692f16cffaa3e77737c5d3050be5528c5046c53
diff --git a/cmds/surfacereplayer/proto/src/trace.proto b/cmds/surfacereplayer/proto/src/trace.proto
index b574098..372cecd 100644
--- a/cmds/surfacereplayer/proto/src/trace.proto
+++ b/cmds/surfacereplayer/proto/src/trace.proto
@@ -53,6 +53,7 @@
         ReparentChildrenChange      reparent_children       = 20;
         BackgroundBlurRadiusChange  background_blur_radius  = 21;
         ShadowRadiusChange          shadow_radius           = 22;
+        TrustedOverlayChange        trusted_overlay         = 23;
     }
 }
 
@@ -208,4 +209,8 @@
 
 message ShadowRadiusChange {
     required float radius = 1;
+}
+
+message TrustedOverlayChange {
+    required float is_trusted_overlay = 1;
 }
\ No newline at end of file
diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h
index 2dac5b6..bbf793e 100644
--- a/include/input/InputWindow.h
+++ b/include/input/InputWindow.h
@@ -108,7 +108,6 @@
         TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW + 32,
         TYPE_DOCK_DIVIDER = FIRST_SYSTEM_WINDOW + 34,
         TYPE_NOTIFICATION_SHADE = FIRST_SYSTEM_WINDOW + 40,
-        TYPE_TRUSTED_APPLICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 42,
         LAST_SYSTEM_WINDOW = 2999,
     };
 
@@ -116,6 +115,7 @@
         INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES = 0x00000001,
         INPUT_FEATURE_NO_INPUT_CHANNEL = 0x00000002,
         INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004,
+        INPUT_FEATURE_DROP_INPUT = 0x00000008,
     };
 
     /* These values are filled in by the WM and passed through SurfaceFlinger
@@ -163,6 +163,12 @@
     bool hasFocus = false;
     bool hasWallpaper = false;
     bool paused = false;
+    /* This flag is set when the window is of a trusted type that is allowed to silently
+     * overlay other windows for the purpose of implementing the secure views feature.
+     * Trusted overlays, such as IME windows, can partly obscure other windows without causing
+     * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
+     */
+    bool trustedOverlay = false;
     int32_t ownerPid = -1;
     int32_t ownerUid = -1;
     int32_t inputFeatures = 0;
@@ -175,20 +181,15 @@
     void addTouchableRegion(const Rect& region);
 
     bool touchableRegionContainsPoint(int32_t x, int32_t y) const;
-    bool frameContainsPoint(int32_t x, int32_t y) const;
 
-    /* Returns true if the window is of a trusted type that is allowed to silently
-     * overlay other windows for the purpose of implementing the secure views feature.
-     * Trusted overlays, such as IME windows, can partly obscure other windows without causing
-     * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
-     */
-    bool isTrustedOverlay() const;
+    bool frameContainsPoint(int32_t x, int32_t y) const;
 
     bool supportsSplitTouch() const;
 
     bool overlaps(const InputWindowInfo* other) const;
 
     status_t write(Parcel& output) const;
+
     static InputWindowInfo read(const Parcel& from);
 };
 
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 4a4510e..6ec1f47 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -30,6 +30,14 @@
     min_sdk_version: "29",
 }
 
+// AIDL files that should be exposed to java
+filegroup {
+    name: "guiconstants_aidl",
+    srcs: [
+        "android/gui/DropInputMode.aidl",
+    ],
+}
+
 cc_library_shared {
     name: "libgui",
     vendor_available: false,
@@ -41,6 +49,7 @@
     defaults: ["libgui_bufferqueue-defaults"],
 
     srcs: [
+        ":guiconstants_aidl",
         ":framework_native_aidl",
         ":libgui_bufferqueue_sources",
 
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index e43446a..dfcef8f 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -117,6 +117,8 @@
     output.writeFloat(frameRate);
     output.writeByte(frameRateCompatibility);
     output.writeUint32(fixedTransformHint);
+    output.writeBool(isTrustedOverlay);
+    output.writeUint32(static_cast<uint32_t>(dropInputMode));
     return NO_ERROR;
 }
 
@@ -200,6 +202,11 @@
     frameRate = input.readFloat();
     frameRateCompatibility = input.readByte();
     fixedTransformHint = static_cast<ui::Transform::RotationFlags>(input.readUint32());
+    isTrustedOverlay = input.readBool();
+
+    uint32_t mode;
+    mode = input.readUint32();
+    dropInputMode = static_cast<gui::DropInputMode>(mode);
     return NO_ERROR;
 }
 
@@ -439,6 +446,14 @@
         what |= eFixedTransformHintChanged;
         fixedTransformHint = other.fixedTransformHint;
     }
+    if (other.what & eTrustedOverlayChanged) {
+        what |= eTrustedOverlayChanged;
+        isTrustedOverlay = other.isTrustedOverlay;
+    }
+    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 83bc069..d2c9621 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1484,6 +1484,34 @@
     return *this;
 }
 
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrustedOverlay(
+        const sp<SurfaceControl>& sc, bool isTrustedOverlay) {
+    layer_state_t* s = getLayerState(sc);
+    if (!s) {
+        mStatus = BAD_INDEX;
+        return *this;
+    }
+
+    s->what |= layer_state_t::eTrustedOverlayChanged;
+    s->isTrustedOverlay = isTrustedOverlay;
+    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..248a031
--- /dev/null
+++ b/libs/gui/android/gui/DropInputMode.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2022, 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,
+}
+
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index e60f677..39dbe9e 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -25,6 +25,7 @@
 #include <gui/ITransactionCompletedListener.h>
 #include <math/mat4.h>
 
+#include <android/gui/DropInputMode.h>
 #ifndef NO_INPUT
 #include <input/InputWindow.h>
 #endif
@@ -105,6 +106,8 @@
         eBackgroundBlurRadiusChanged = 0x80'00000000,
         eProducerDisconnect = 0x100'00000000,
         eFixedTransformHintChanged = 0x200'00000000,
+        eTrustedOverlayChanged = 0x400'00000000,
+        eDropInputModeChanged = 0x8000'00000000,
     };
 
     layer_state_t()
@@ -139,7 +142,9 @@
             frameRateSelectionPriority(-1),
             frameRate(0.0f),
             frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT),
-            fixedTransformHint(ui::Transform::ROT_INVALID) {
+            fixedTransformHint(ui::Transform::ROT_INVALID),
+            isTrustedOverlay(false),
+            dropInputMode(gui::DropInputMode::NONE) {
         matrix.dsdx = matrix.dtdy = 1.0f;
         matrix.dsdy = matrix.dtdx = 0.0f;
         hdrMetadata.validTypes = 0;
@@ -237,6 +242,13 @@
     // a buffer of a different size. -1 means the transform hint is not set,
     // otherwise the value will be a valid ui::Rotation.
     ui::Transform::RotationFlags fixedTransformHint;
+
+    // An inherited state that indicates that this surface control and its children
+    // should be trusted for input occlusion detection purposes
+    bool isTrustedOverlay;
+
+    // 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 adcb898..2e189e5 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -529,6 +529,10 @@
         // a buffer of a different size.
         Transaction& setFixedTransformHint(const sp<SurfaceControl>& sc, int32_t transformHint);
 
+        // Sets that this surface control and its children are trusted overlays for input
+        Transaction& setTrustedOverlay(const sp<SurfaceControl>& sc, bool isTrustedOverlay);
+
+        Transaction& setDropInputMode(const sp<SurfaceControl>& sc, gui::DropInputMode mode);
         status_t setDisplaySurface(const sp<IBinder>& token,
                 const sp<IGraphicBufferProducer>& bufferProducer);
 
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index b1d3ecb..e3f4798 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -24,6 +24,7 @@
 
 #include <memory>
 
+#include <android/keycodes.h>
 #include <android/native_window.h>
 
 #include <binder/Binder.h>
@@ -65,17 +66,40 @@
 
 class InputSurface {
 public:
-    InputSurface(const sp<SurfaceControl> &sc, int width, int height) {
+    InputSurface(const sp<SurfaceControl> &sc, int width, int height, bool noInputChannel = false) {
         mSurfaceControl = sc;
 
-        InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel);
-
         mInputFlinger = getInputFlinger();
-        mInputFlinger->registerInputChannel(mServerChannel);
+        if (noInputChannel) {
+            mInputInfo.inputFeatures = InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
+        } else {
+            InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel);
+            mInputFlinger->registerInputChannel(mServerChannel);
+            mInputInfo.token = mServerChannel->getConnectionToken();
+            mInputConsumer = new InputConsumer(mClientChannel);
+        }
 
-        populateInputInfo(width, height);
+        mInputInfo.name = "Test info";
+        mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL;
+        mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION;
+        mInputInfo.dispatchingTimeout = seconds_to_nanoseconds(5);
+        mInputInfo.globalScaleFactor = 1.0;
+        mInputInfo.canReceiveKeys = true;
+        mInputInfo.hasFocus = true;
+        mInputInfo.hasWallpaper = false;
+        mInputInfo.paused = false;
+        mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));
+        // TODO: Fill in from SF?
+        mInputInfo.ownerPid = 11111;
+        mInputInfo.ownerUid = 11111;
+        mInputInfo.inputFeatures = 0;
+        mInputInfo.displayId = 0;
 
-        mInputConsumer = new InputConsumer(mClientChannel);
+        InputApplicationInfo aInfo;
+        aInfo.token = new BBinder();
+        aInfo.name = "Test app info";
+        aInfo.dispatchingTimeout = seconds_to_nanoseconds(5);
+        mInputInfo.applicationInfo = aInfo;
     }
 
     static std::unique_ptr<InputSurface> makeColorInputSurface(const sp<SurfaceComposerClient> &scc,
@@ -104,6 +128,16 @@
         return std::make_unique<InputSurface>(surfaceControl, width, height);
     }
 
+    static std::unique_ptr<InputSurface> makeContainerInputSurfaceNoInputChannel(
+            const sp<SurfaceComposerClient> &scc, int width, int height) {
+        sp<SurfaceControl> surfaceControl =
+                scc->createSurface(String8("Test Container Surface"), 0 /* bufHeight */,
+                                   0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
+                                   ISurfaceComposerClient::eFXSurfaceContainer);
+        return std::make_unique<InputSurface>(surfaceControl, width, height,
+                                              true /* noInputChannel */);
+    }
+
     static std::unique_ptr<InputSurface> makeCursorInputSurface(
             const sp<SurfaceComposerClient> &scc, int width, int height) {
         sp<SurfaceControl> surfaceControl =
@@ -113,8 +147,8 @@
         return std::make_unique<InputSurface>(surfaceControl, width, height);
     }
 
-    InputEvent* consumeEvent() {
-        waitForEventAvailable();
+    InputEvent *consumeEvent(int timeoutMs = 3000) {
+        waitForEventAvailable(timeoutMs);
 
         InputEvent *ev;
         uint32_t seqId;
@@ -153,8 +187,28 @@
         EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
     }
 
+    void expectKey(uint32_t keycode) {
+        InputEvent *ev = consumeEvent();
+        ASSERT_NE(ev, nullptr);
+        ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, ev->getType());
+        KeyEvent *keyEvent = static_cast<KeyEvent *>(ev);
+        EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, keyEvent->getAction());
+        EXPECT_EQ(keycode, keyEvent->getKeyCode());
+        EXPECT_EQ(0, keyEvent->getFlags() & VERIFIED_KEY_EVENT_FLAGS);
+
+        ev = consumeEvent();
+        ASSERT_NE(ev, nullptr);
+        ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, ev->getType());
+        keyEvent = static_cast<KeyEvent *>(ev);
+        EXPECT_EQ(AMOTION_EVENT_ACTION_UP, keyEvent->getAction());
+        EXPECT_EQ(keycode, keyEvent->getKeyCode());
+        EXPECT_EQ(0, keyEvent->getFlags() & VERIFIED_KEY_EVENT_FLAGS);
+    }
+
     ~InputSurface() {
-        mInputFlinger->unregisterInputChannel(mServerChannel);
+        if (mInputInfo.token) {
+            mInputFlinger->unregisterInputChannel(mServerChannel);
+        }
     }
 
     void doTransaction(std::function<void(SurfaceComposerClient::Transaction&,
@@ -176,41 +230,14 @@
     }
 
 private:
-    void waitForEventAvailable() {
+    void waitForEventAvailable(int timeoutMs) {
         struct pollfd fd;
 
         fd.fd = mClientChannel->getFd();
         fd.events = POLLIN;
-        poll(&fd, 1, 3000);
+        poll(&fd, 1, timeoutMs);
     }
 
-    void populateInputInfo(int width, int height) {
-        mInputInfo.token = mServerChannel->getConnectionToken();
-        mInputInfo.name = "Test info";
-        mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL;
-        mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION;
-        mInputInfo.dispatchingTimeout = seconds_to_nanoseconds(5);
-        mInputInfo.globalScaleFactor = 1.0;
-        mInputInfo.canReceiveKeys = true;
-        mInputInfo.hasFocus = true;
-        mInputInfo.hasWallpaper = false;
-        mInputInfo.paused = false;
-
-        mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));
-
-        // TODO: Fill in from SF?
-        mInputInfo.ownerPid = 11111;
-        mInputInfo.ownerUid = 11111;
-        mInputInfo.inputFeatures = 0;
-        mInputInfo.displayId = 0;
-
-        InputApplicationInfo aInfo;
-        aInfo.token = new BBinder();
-        aInfo.name = "Test app info";
-        aInfo.dispatchingTimeout = seconds_to_nanoseconds(5);
-
-        mInputInfo.applicationInfo = aInfo;
-    }
 public:
     sp<SurfaceControl> mSurfaceControl;
     sp<InputChannel> mServerChannel, mClientChannel;
@@ -277,6 +304,14 @@
     }
 }
 
+void injectKey(uint32_t keycode) {
+    char *buf1;
+    asprintf(&buf1, "%d", keycode);
+    if (fork() == 0) {
+        execlp("input", "input", "keyevent", buf1, NULL);
+    }
+}
+
 TEST_F(InputSurfacesTest, can_receive_input) {
     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
     surface->showAt(100, 100);
@@ -561,5 +596,36 @@
     injectTap(11, 11);
     surface->expectTap(1, 1);
 }
+
+TEST_F(InputSurfacesTest, child_container_with_no_input_channel_blocks_parent) {
+    std::unique_ptr<InputSurface> parent = makeSurface(100, 100);
+    parent->showAt(100, 100);
+    parent->assertFocusChange(true);
+    injectTap(101, 101);
+    parent->expectTap(1, 1);
+
+    std::unique_ptr<InputSurface> childContainerSurface =
+            InputSurface::makeContainerInputSurfaceNoInputChannel(mComposerClient, 100, 100);
+    childContainerSurface->showAt(0, 0);
+    childContainerSurface->doTransaction(
+            [&](auto &t, auto &sc) { t.reparent(sc, parent->mSurfaceControl->getHandle()); });
+    injectTap(101, 101);
+
+    EXPECT_EQ(parent->consumeEvent(100), nullptr);
+}
+
+TEST_F(InputSurfacesTest, drop_input_policy) {
+    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
+    surface->doTransaction(
+            [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::ALL); });
+    surface->showAt(100, 100);
+    surface->assertFocusChange(true);
+
+    injectTap(101, 101);
+    EXPECT_EQ(surface->consumeEvent(100), nullptr);
+
+    injectKey(AKEYCODE_V);
+    EXPECT_EQ(surface->consumeEvent(100), nullptr);
 }
 }
+} // namespace android
\ No newline at end of file
diff --git a/libs/input/InputWindow.cpp b/libs/input/InputWindow.cpp
index 85a2015..301c3f5 100644
--- a/libs/input/InputWindow.cpp
+++ b/libs/input/InputWindow.cpp
@@ -42,20 +42,6 @@
             && y >= frameTop && y < frameBottom;
 }
 
-// TODO(b/155781676): Remove and replace call points with trustedOverlay when that is ready.
-bool InputWindowInfo::isTrustedOverlay() const {
-    return layoutParamsType == TYPE_INPUT_METHOD || layoutParamsType == TYPE_INPUT_METHOD_DIALOG ||
-            layoutParamsType == TYPE_MAGNIFICATION_OVERLAY || layoutParamsType == TYPE_STATUS_BAR ||
-            layoutParamsType == TYPE_NOTIFICATION_SHADE ||
-            layoutParamsType == TYPE_NAVIGATION_BAR ||
-            layoutParamsType == TYPE_NAVIGATION_BAR_PANEL ||
-            layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY ||
-            layoutParamsType == TYPE_DOCK_DIVIDER ||
-            layoutParamsType == TYPE_ACCESSIBILITY_OVERLAY ||
-            layoutParamsType == TYPE_INPUT_CONSUMER ||
-            layoutParamsType == TYPE_TRUSTED_APPLICATION_OVERLAY;
-}
-
 bool InputWindowInfo::supportsSplitTouch() const {
     return layoutParamsFlags & FLAG_SPLIT_TOUCH;
 }
@@ -92,6 +78,7 @@
     output.writeBool(hasFocus);
     output.writeBool(hasWallpaper);
     output.writeBool(paused);
+    output.writeBool(trustedOverlay);
     output.writeInt32(ownerPid);
     output.writeInt32(ownerUid);
     output.writeInt32(inputFeatures);
@@ -130,6 +117,7 @@
     ret.hasFocus = from.readBool();
     ret.hasWallpaper = from.readBool();
     ret.paused = from.readBool();
+    ret.trustedOverlay = from.readBool();
     ret.ownerPid = from.readInt32();
     ret.ownerUid = from.readInt32();
     ret.inputFeatures = from.readInt32();
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 8907b35..e3ab522 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1465,6 +1465,11 @@
         return INPUT_EVENT_INJECTION_FAILED;
     }
 
+    // Drop key events if requested by input feature
+    if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
+        return INPUT_EVENT_INJECTION_FAILED;
+    }
+
     // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
     // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
     // start interacting with another application via touch (app switch). This code can be removed
@@ -1694,6 +1699,11 @@
             }
         }
 
+        // Drop touch events if requested by input feature
+        if (newTouchedWindowHandle != nullptr && shouldDropInput(entry, newTouchedWindowHandle)) {
+            newTouchedWindowHandle = nullptr;
+        }
+
         // Also don't send the new touch event to unresponsive gesture monitors
         newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
 
@@ -1758,6 +1768,13 @@
                     tempTouchState.getFirstForegroundWindowHandle();
             sp<InputWindowHandle> newTouchedWindowHandle =
                     findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
+
+            // Drop touch events if requested by input feature
+            if (newTouchedWindowHandle != nullptr &&
+                shouldDropInput(entry, newTouchedWindowHandle)) {
+                newTouchedWindowHandle = nullptr;
+            }
+
             if (oldTouchedWindowHandle != newTouchedWindowHandle &&
                 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
                 if (DEBUG_FOCUS) {
@@ -2094,7 +2111,7 @@
         // If ownerPid is the same we don't generate occlusion events as there
         // is no in-process security boundary.
         return false;
-    } else if (otherInfo->isTrustedOverlay()) {
+    } else if (otherInfo->trustedOverlay) {
         return false;
     } else if (otherInfo->displayId != info->displayId) {
         return false;
@@ -5099,4 +5116,16 @@
     return result == std::cv_status::no_timeout;
 }
 
+bool InputDispatcher::shouldDropInput(const EventEntry& entry,
+                                      const sp<InputWindowHandle>& windowHandle) const {
+    if (windowHandle->getInfo()->inputFeatures & InputWindowInfo::INPUT_FEATURE_DROP_INPUT) {
+        ALOGW("Dropping %s event targeting %s as requested by inputFeatures=0x%08x on display "
+              "%" PRId32 ".",
+              EventEntry::typeToString(entry.type), windowHandle->getName().c_str(),
+              windowHandle->getInfo()->inputFeatures, windowHandle->getInfo()->displayId);
+        return true;
+    }
+    return false;
+}
+
 } // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index e679c6b..b078662 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -420,6 +420,9 @@
     std::string getApplicationWindowLabel(const sp<InputApplicationHandle>& applicationHandle,
                                           const sp<InputWindowHandle>& windowHandle);
 
+    bool shouldDropInput(const EventEntry& entry, const sp<InputWindowHandle>& windowHandle) const
+            REQUIRES(mLock);
+
     // Manage the dispatch cycle for a single connection.
     // These methods are deliberately not Interruptible because doing all of the work
     // with the mutex held makes it easier to ensure that connection invariants are maintained.
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 86c0503..6842e6c 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -785,6 +785,8 @@
 
     void setFocus(bool hasFocus) { mInfo.hasFocus = hasFocus; }
 
+    void setInputFeatures(int32_t inputFeatures) { mInfo.inputFeatures = inputFeatures; }
+
     void setDispatchingTimeout(std::chrono::nanoseconds timeout) {
         mInfo.dispatchingTimeout = timeout.count();
     }
@@ -903,6 +905,8 @@
         mInfo.ownerUid = ownerUid;
     }
 
+    void setFlags(int32_t layoutParamsFlags) { mInfo.layoutParamsFlags = layoutParamsFlags; }
+
 private:
     const std::string mName;
     std::unique_ptr<FakeInputReceiver> mInputReceiver;
@@ -3112,4 +3116,42 @@
     mFocusedWindow->assertNoEvents();
 }
 
+class InputDispatcherDropInputFeatureTest : public InputDispatcherTest {};
+
+TEST_F(InputDispatcherDropInputFeatureTest, WindowDropsInput) {
+    sp<FakeApplicationHandle> application = new FakeApplicationHandle();
+    sp<FakeWindowHandle> window =
+            new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
+    window->setInputFeatures(InputWindowInfo::INPUT_FEATURE_DROP_INPUT);
+    mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
+    window->setFocus(true);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
+
+    // With the flag set, window should not get any input
+    NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
+    mDispatcher->notifyKey(&keyArgs);
+    window->assertNoEvents();
+
+    NotifyMotionArgs motionArgs =
+            generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
+                               ADISPLAY_ID_DEFAULT);
+    mDispatcher->notifyMotion(&motionArgs);
+    window->assertNoEvents();
+
+    // With the flag cleared, the window should get input
+    window->setInputFeatures(0);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+
+    keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT);
+    mDispatcher->notifyKey(&keyArgs);
+    window->consumeKeyUp(ADISPLAY_ID_DEFAULT);
+
+    motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
+                                    ADISPLAY_ID_DEFAULT);
+    mDispatcher->notifyMotion(&motionArgs);
+    window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
+    window->assertNoEvents();
+}
+
 } // namespace android::inputdispatcher
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index e9965d4..6215d5c 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -118,6 +118,8 @@
     mCurrentState.shadowRadius = 0.f;
     mCurrentState.treeHasFrameRateVote = false;
     mCurrentState.fixedTransformHint = ui::Transform::ROT_INVALID;
+    mCurrentState.isTrustedOverlay = false;
+    mCurrentState.dropInputMode = gui::DropInputMode::NONE;
 
     if (args.flags & ISurfaceComposerClient::eNoColorFill) {
         // Set an invalid color so there is no color fill.
@@ -1142,6 +1144,23 @@
     return true;
 }
 
+bool Layer::setTrustedOverlay(bool isTrustedOverlay) {
+    if (mCurrentState.isTrustedOverlay == isTrustedOverlay) return false;
+    mCurrentState.isTrustedOverlay = isTrustedOverlay;
+    mCurrentState.modified = true;
+    mCurrentState.inputInfoChanged = true;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+
+bool Layer::isTrustedOverlay() const {
+    if (getDrawingState().isTrustedOverlay) {
+        return true;
+    }
+    const auto& p = mDrawingParent.promote();
+    return (p != nullptr) && p->isTrustedOverlay();
+}
+
 bool Layer::setSize(uint32_t w, uint32_t h) {
     if (mCurrentState.requested_legacy.w == w && mCurrentState.requested_legacy.h == h)
         return false;
@@ -2252,6 +2271,7 @@
         layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
 
         layerInfo->set_corner_radius(getRoundedCornerState().radius);
+        layerInfo->set_is_trusted_overlay(isTrustedOverlay());
         LayerProtoHelper::writeToProto(transform, layerInfo->mutable_transform());
         LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
                                                [&]() { return layerInfo->mutable_position(); });
@@ -2365,6 +2385,36 @@
     return mRemovedFromCurrentState;
 }
 
+gui::DropInputMode Layer::getDropInputMode() const {
+    gui::DropInputMode mode = mDrawingState.dropInputMode;
+    if (mode == gui::DropInputMode::ALL) {
+        return mode;
+    }
+    sp<Layer> parent = mDrawingParent.promote();
+    if (parent) {
+        gui::DropInputMode parentMode = parent->getDropInputMode();
+        if (parentMode != gui::DropInputMode::NONE) {
+            return parentMode;
+        }
+    }
+    return mode;
+}
+
+void Layer::handleDropInputMode(InputWindowInfo& info) const {
+    if ((mDrawingState.inputInfo.inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL) ==
+        InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL) {
+        return;
+    }
+
+    // Check if we need to drop input unconditionally
+    gui::DropInputMode dropInputMode = getDropInputMode();
+    if (dropInputMode == gui::DropInputMode::ALL) {
+        info.inputFeatures |= InputWindowInfo::INPUT_FEATURE_DROP_INPUT;
+        ALOGV("Dropping input for %s as requested by policy.", getDebugName());
+        return;
+    }
+}
+
 InputWindowInfo Layer::fillInputInfo() {
     if (!hasInputInfo()) {
         mDrawingState.inputInfo.name = getName();
@@ -2438,6 +2488,7 @@
     // InputDispatcher, and obviously if they aren't visible they can't occlude
     // anything.
     info.visible = hasInputInfo() ? canReceiveInput() : isVisible();
+    handleDropInputMode(info);
 
     auto cropLayer = mDrawingState.touchableRegionCrop.promote();
     if (info.replaceTouchableRegionWithCrop) {
@@ -2450,6 +2501,10 @@
         info.touchableRegion = info.touchableRegion.intersect(Rect{cropLayer->mScreenBounds});
     }
 
+    // Inherit the trusted state from the parent hierarchy, but don't clobber the trusted state
+    // if it was set by WM for a known system overlay
+    info.trustedOverlay = info.trustedOverlay || isTrustedOverlay();
+
     // If the layer is a clone, we need to crop the input region to cloned root to prevent
     // touches from going outside the cloned area.
     if (isClone()) {
@@ -2474,7 +2529,8 @@
 }
 
 bool Layer::hasInputInfo() const {
-    return mDrawingState.inputInfo.token != nullptr;
+    return mDrawingState.inputInfo.token != nullptr ||
+            mDrawingState.inputInfo.inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
 }
 
 bool Layer::canReceiveInput() const {
@@ -2637,6 +2693,16 @@
     }
 }
 
+bool Layer::setDropInputMode(gui::DropInputMode mode) {
+    if (mCurrentState.dropInputMode == mode) {
+        return false;
+    }
+    mCurrentState.dropInputMode = mode;
+    mCurrentState.modified = true;
+    mCurrentState.inputInfoChanged = true;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 2c90c92..6c5d114 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <android/gui/DropInputMode.h>
 #include <compositionengine/LayerFE.h>
 #include <gui/BufferQueue.h>
 #include <gui/ISurfaceComposerClient.h>
@@ -279,6 +280,11 @@
         // a buffer of a different size. ui::Transform::ROT_INVALID means the
         // a fixed transform hint is not set.
         ui::Transform::RotationFlags fixedTransformHint;
+
+        // Whether or not this layer is a trusted overlay for input
+        bool isTrustedOverlay;
+
+        gui::DropInputMode dropInputMode;
     };
 
     explicit Layer(const LayerCreationArgs& args);
@@ -356,6 +362,7 @@
     // is specified in pixels.
     virtual bool setBackgroundBlurRadius(int backgroundBlurRadius);
     virtual bool setTransparentRegionHint(const Region& transparent);
+    virtual bool setTrustedOverlay(bool);
     virtual bool setFlags(uint8_t flags, uint8_t mask);
     virtual bool setLayerStack(uint32_t layerStack);
     virtual uint32_t getLayerStack() const;
@@ -406,6 +413,8 @@
     bool setShadowRadius(float shadowRadius);
     virtual bool setFrameRateSelectionPriority(int32_t priority);
     virtual bool setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHint);
+    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;
@@ -1064,6 +1073,9 @@
                                           const std::vector<Layer*>& layersInTree);
 
     void updateTreeHasFrameRateVote();
+    bool isTrustedOverlay() const;
+    gui::DropInputMode getDropInputMode() const;
+    void handleDropInputMode(InputWindowInfo& info) const;
 
     // Cached properties computed from drawing state
     // Effective transform taking into account parent transforms and any parent scaling.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 79f99cc..0d95819 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3859,6 +3859,24 @@
             flags |= eTraversalNeeded | eTransformHintUpdateNeeded;
         }
     }
+    if (what & layer_state_t::eTrustedOverlayChanged) {
+        if (privileged) {
+            if (layer->setTrustedOverlay(s.isTrustedOverlay)) {
+                flags |= eTraversalNeeded;
+            }
+        } else {
+            ALOGE("Attempt to set trusted overlay without permission ACCESS_SURFACE_FLINGER");
+        }
+    }
+    if (what & layer_state_t::eDropInputModeChanged) {
+        if (privileged) {
+            if (layer->setDropInputMode(s.dropInputMode)) {
+                flags |= eTraversalNeeded;
+            }
+        } 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
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 80102bd..0555acf 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -130,6 +130,7 @@
                             getLayerIdFromWeakRef(layer->mCurrentState.zOrderRelativeOf),
                             layer->mCurrentState.z);
     addShadowRadiusLocked(transaction, layerId, layer->mCurrentState.shadowRadius);
+    addTrustedOverlayLocked(transaction, layerId, layer->mDrawingState.isTrustedOverlay);
 }
 
 void SurfaceInterceptor::addInitialDisplayStateLocked(Increment* increment,
@@ -388,6 +389,13 @@
     overrideChange->set_radius(shadowRadius);
 }
 
+void SurfaceInterceptor::addTrustedOverlayLocked(Transaction* transaction, int32_t layerId,
+                                                 bool isTrustedOverlay) {
+    SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId));
+    TrustedOverlayChange* overrideChange(change->mutable_trusted_overlay());
+    overrideChange->set_is_trusted_overlay(isTrustedOverlay);
+}
+
 void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction,
         const layer_state_t& state)
 {
@@ -467,6 +475,9 @@
     if (state.what & layer_state_t::eShadowRadiusChanged) {
         addShadowRadiusLocked(transaction, layerId, state.shadowRadius);
     }
+    if (state.what & layer_state_t::eTrustedOverlayChanged) {
+        addTrustedOverlayLocked(transaction, layerId, state.isTrustedOverlay);
+    }
 }
 
 void SurfaceInterceptor::addDisplayChangesLocked(Transaction* transaction,
diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h
index 896bdcc..6b98b44 100644
--- a/services/surfaceflinger/SurfaceInterceptor.h
+++ b/services/surfaceflinger/SurfaceInterceptor.h
@@ -168,6 +168,7 @@
     void addRelativeParentLocked(Transaction* transaction, int32_t layerId, int32_t parentId,
                                  int z);
     void addShadowRadiusLocked(Transaction* transaction, int32_t layerId, float shadowRadius);
+    void addTrustedOverlayLocked(Transaction* transaction, int32_t layerId, bool isTrustedOverlay);
 
     // Add display transactions to the trace
     DisplayChange* createDisplayChangeLocked(Transaction* transaction, int32_t sequenceId);
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index 8fce0c9..2eceba8 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -105,6 +105,7 @@
     layer.queuedFrames = layerProto.queued_frames();
     layer.refreshPending = layerProto.refresh_pending();
     layer.isProtected = layerProto.is_protected();
+    layer.isTrustedOverlay = layerProto.is_trusted_overlay();
     layer.cornerRadius = layerProto.corner_radius();
     layer.backgroundBlurRadius = layerProto.background_blur_radius();
     for (const auto& entry : layerProto.metadata()) {
@@ -288,6 +289,7 @@
     StringAppendF(&result, "crop=%s, ", crop.to_string().c_str());
     StringAppendF(&result, "cornerRadius=%f, ", cornerRadius);
     StringAppendF(&result, "isProtected=%1d, ", isProtected);
+    StringAppendF(&result, "isTrustedOverlay=%1d, ", isTrustedOverlay);
     StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate);
     StringAppendF(&result, "dataspace=%s, ", dataspace.c_str());
     StringAppendF(&result, "defaultPixelFormat=%s, ", pixelFormat.c_str());
diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
index 52b9165..67bbd76 100644
--- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
+++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
@@ -109,6 +109,7 @@
         int32_t queuedFrames;
         bool refreshPending;
         bool isProtected;
+        bool isTrustedOverlay;
         float cornerRadius;
         int backgroundBlurRadius;
         LayerMetadata metadata;
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index 7f1f542..780b066 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -123,6 +123,8 @@
   bool is_relative_of = 51;
   // Layer's background blur radius in pixels.
   int32 background_blur_radius = 52;
+
+  bool is_trusted_overlay = 53;
 }
 
 message PositionProto {
diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
index 8d97f27..5bafbd8 100644
--- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
+++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
@@ -195,6 +195,7 @@
     bool detachChildrenUpdateFound(const SurfaceChange& change, bool found);
     bool reparentChildrenUpdateFound(const SurfaceChange& change, bool found);
     bool shadowRadiusUpdateFound(const SurfaceChange& change, bool found);
+    bool trustedOverlayUpdateFound(const SurfaceChange& change, bool found);
     bool surfaceUpdateFound(const Trace& trace, SurfaceChange::SurfaceChangeCase changeCase);
 
     // Find all of the updates in the single trace
@@ -233,6 +234,7 @@
     void detachChildrenUpdate(Transaction&);
     void reparentChildrenUpdate(Transaction&);
     void shadowRadiusUpdate(Transaction&);
+    void trustedOverlayUpdate(Transaction&);
     void surfaceCreation(Transaction&);
     void displayCreation(Transaction&);
     void displayDeletion(Transaction&);
@@ -421,6 +423,10 @@
     t.setShadowRadius(mBGSurfaceControl, SHADOW_RADIUS_UPDATE);
 }
 
+void SurfaceInterceptorTest::trustedOverlayUpdate(Transaction& t) {
+    t.setTrustedOverlay(mBGSurfaceControl, true);
+}
+
 void SurfaceInterceptorTest::displayCreation(Transaction&) {
     sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
     SurfaceComposerClient::destroyDisplay(testDisplay);
@@ -452,6 +458,7 @@
     runInTransaction(&SurfaceInterceptorTest::detachChildrenUpdate);
     runInTransaction(&SurfaceInterceptorTest::relativeParentUpdate);
     runInTransaction(&SurfaceInterceptorTest::shadowRadiusUpdate);
+    runInTransaction(&SurfaceInterceptorTest::trustedOverlayUpdate);
 }
 
 void SurfaceInterceptorTest::surfaceCreation(Transaction&) {
@@ -695,6 +702,17 @@
     return foundShadowRadius;
 }
 
+bool SurfaceInterceptorTest::trustedOverlayUpdateFound(const SurfaceChange& change,
+                                                       bool foundTrustedOverlay) {
+    bool hasTrustedOverlay(change.trusted_overlay().is_trusted_overlay());
+    if (hasTrustedOverlay && !foundTrustedOverlay) {
+        foundTrustedOverlay = true;
+    } else if (hasTrustedOverlay && foundTrustedOverlay) {
+        []() { FAIL(); }();
+    }
+    return foundTrustedOverlay;
+}
+
 bool SurfaceInterceptorTest::surfaceUpdateFound(const Trace& trace,
         SurfaceChange::SurfaceChangeCase changeCase) {
     bool foundUpdate = false;
@@ -764,6 +782,9 @@
                         case SurfaceChange::SurfaceChangeCase::kShadowRadius:
                             foundUpdate = shadowRadiusUpdateFound(change, foundUpdate);
                             break;
+                        case SurfaceChange::SurfaceChangeCase::kTrustedOverlay:
+                            foundUpdate = trustedOverlayUpdateFound(change, foundUpdate);
+                            break;
                         case SurfaceChange::SurfaceChangeCase::SURFACECHANGE_NOT_SET:
                             break;
                     }
@@ -976,6 +997,11 @@
                 SurfaceChange::SurfaceChangeCase::kShadowRadius);
 }
 
+TEST_F(SurfaceInterceptorTest, InterceptTrustedOverlayUpdateWorks) {
+    captureTest(&SurfaceInterceptorTest::trustedOverlayUpdate,
+                SurfaceChange::SurfaceChangeCase::kTrustedOverlay);
+}
+
 TEST_F(SurfaceInterceptorTest, InterceptAllUpdatesWorks) {
     captureTest(&SurfaceInterceptorTest::runAllUpdates,
                 &SurfaceInterceptorTest::assertAllUpdatesFound);