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
Change-Id: I443741d5ab51a45d37fb865f11c433c436d96c1e
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 2d1f5a1..8c359c7 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -55,6 +55,7 @@
filegroup {
name: "guiconstants_aidl",
srcs: [
+ "android/gui/DropInputMode.aidl",
"android/**/TouchOcclusionMode.aidl",
],
}
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 1fd9d13..a419a63 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -69,7 +69,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;
@@ -174,6 +175,7 @@
SAFE_PARCEL(output.writeBool, isTrustedOverlay);
SAFE_PARCEL(output.writeStrongBinder, releaseBufferEndpoint);
+ SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(dropInputMode));
return NO_ERROR;
}
@@ -304,6 +306,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;
}
@@ -558,6 +564,10 @@
if (other.what & eProducerDisconnect) {
what |= eProducerDisconnect;
}
+ 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%" PRIX64 " what=0x%" PRIX64 " unmerged flags=0x%" PRIX64,
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 1bca6f9..64361db 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 f14127c..b27102b 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>
@@ -118,6 +119,7 @@
eAutoRefreshChanged = 0x1000'00000000,
eStretchChanged = 0x2000'00000000,
eTrustedOverlayChanged = 0x4000'00000000,
+ eDropInputModeChanged = 0x8000'00000000,
};
layer_state_t();
@@ -248,6 +250,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 baa6878..ffd0244 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);