summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-12-06 02:39:56 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-12-06 02:39:56 +0000
commit0652bec39b63ae07a96bb3f8ae8a4309ccf2d66f (patch)
tree2b25d3dde8be8b4b5126ec7e3adf3938acc5c032
parent7b91109f8da100e8b8ba7a3b56267d50af412b91 (diff)
parent0999fe2ab4d1063b4b788457b6356a390da06d61 (diff)
downloadnative-android11-gsi.tar.gz
Merge "Merge cherrypicks of [15975347, 15975348, 15975349, 16508592, 16508593, 16508594, 18029504] into rvc-platform-release. am: 95af48052c" into android11-gsiandroid11-gsi
-rw-r--r--cmds/surfacereplayer/proto/src/trace.proto5
-rw-r--r--include/input/InputWindow.h17
-rw-r--r--libs/gui/Android.bp9
-rw-r--r--libs/gui/LayerState.cpp15
-rw-r--r--libs/gui/SurfaceComposerClient.cpp28
-rw-r--r--libs/gui/android/gui/DropInputMode.aidl40
-rw-r--r--libs/gui/include/gui/LayerState.h14
-rw-r--r--libs/gui/include/gui/SurfaceComposerClient.h4
-rw-r--r--libs/gui/tests/EndToEndNativeInputTest.cpp142
-rw-r--r--libs/input/InputWindow.cpp16
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp31
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.h3
-rw-r--r--services/inputflinger/tests/InputDispatcher_test.cpp42
-rw-r--r--services/surfaceflinger/Layer.cpp68
-rw-r--r--services/surfaceflinger/Layer.h12
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp18
-rw-r--r--services/surfaceflinger/SurfaceInterceptor.cpp11
-rw-r--r--services/surfaceflinger/SurfaceInterceptor.h1
-rw-r--r--services/surfaceflinger/layerproto/LayerProtoParser.cpp2
-rw-r--r--services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h1
-rw-r--r--services/surfaceflinger/layerproto/layers.proto2
-rw-r--r--services/surfaceflinger/tests/SurfaceInterceptor_test.cpp26
22 files changed, 444 insertions, 63 deletions
diff --git a/cmds/surfacereplayer/proto/src/trace.proto b/cmds/surfacereplayer/proto/src/trace.proto
index b57409867f..372cecd63c 100644
--- a/cmds/surfacereplayer/proto/src/trace.proto
+++ b/cmds/surfacereplayer/proto/src/trace.proto
@@ -53,6 +53,7 @@ message SurfaceChange {
ReparentChildrenChange reparent_children = 20;
BackgroundBlurRadiusChange background_blur_radius = 21;
ShadowRadiusChange shadow_radius = 22;
+ TrustedOverlayChange trusted_overlay = 23;
}
}
@@ -208,4 +209,8 @@ message DetachChildrenChange {
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 2dac5b62a7..bbf793e62b 100644
--- a/include/input/InputWindow.h
+++ b/include/input/InputWindow.h
@@ -108,7 +108,6 @@ struct InputWindowInfo {
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 @@ struct InputWindowInfo {
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 @@ struct InputWindowInfo {
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 @@ struct InputWindowInfo {
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 4a4510e047..6ec1f471c3 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -30,6 +30,14 @@ cc_library_headers {
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 @@ cc_library_shared {
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 e43446ac8c..dfcef8fe7a 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -117,6 +117,8 @@ status_t layer_state_t::write(Parcel& output) const
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 @@ status_t layer_state_t::read(const Parcel& input)
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 @@ void layer_state_t::merge(const layer_state_t& other) {
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 83bc06997a..d2c96218f4 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1484,6 +1484,34 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFixed
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 0000000000..248a0318b7
--- /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 e60f6777ae..39dbe9e035 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 @@ struct layer_state_t {
eBackgroundBlurRadiusChanged = 0x80'00000000,
eProducerDisconnect = 0x100'00000000,
eFixedTransformHintChanged = 0x200'00000000,
+ eTrustedOverlayChanged = 0x400'00000000,
+ eDropInputModeChanged = 0x8000'00000000,
};
layer_state_t()
@@ -139,7 +142,9 @@ struct layer_state_t {
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 @@ struct layer_state_t {
// 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 adcb8982a0..2e189e5d89 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -529,6 +529,10 @@ public:
// 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 b1d3ecbf36..e3f4798019 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 @@ static const int LAYER_BASE = INT32_MAX - 10;
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
}
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 injectTap(int x, int y) {
}
}
+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 @@ TEST_F(InputSurfacesTest, input_ignores_cursor_layer) {
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 85a2015e43..301c3f56f2 100644
--- a/libs/input/InputWindow.cpp
+++ b/libs/input/InputWindow.cpp
@@ -42,20 +42,6 @@ bool InputWindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
&& 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 @@ status_t InputWindowInfo::write(Parcel& output) const {
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 @@ InputWindowInfo InputWindowInfo::read(const Parcel& from) {
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 8907b3576d..e3ab522d6d 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1465,6 +1465,11 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
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 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
}
}
+ // 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 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
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 @@ static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
// 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 @@ bool InputDispatcher::waitForIdle() {
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 e679c6b06f..b078662870 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -420,6 +420,9 @@ private:
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 86c0503662..6842e6cd33 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -785,6 +785,8 @@ public:
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 @@ public:
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 @@ TEST_F(InputDispatcherMultiWindowAnr, SplitTouch_SingleWindowAnr) {
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 e9965d4717..6215d5cecc 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -118,6 +118,8 @@ Layer::Layer(const LayerCreationArgs& args)
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 @@ bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relati
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 @@ void Layer::writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags,
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 @@ bool Layer::isRemovedFromCurrentState() const {
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 @@ InputWindowInfo Layer::fillInputInfo() {
// 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 @@ InputWindowInfo Layer::fillInputInfo() {
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 @@ sp<Layer> Layer::getClonedRoot() {
}
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 @@ Layer::FrameRateCompatibility Layer::FrameRate::convertCompatibility(int8_t comp
}
}
+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 2c90c92f6c..6c5d114f86 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 @@ public:
// 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 @@ public:
// 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 @@ public:
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 @@ private:
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 79f99cc5d5..0d95819497 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3859,6 +3859,24 @@ uint32_t SurfaceFlinger::setClientStateLocked(
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 80102bdbb6..0555acff43 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -130,6 +130,7 @@ void SurfaceInterceptor::addInitialSurfaceStateLocked(Increment* increment,
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 @@ void SurfaceInterceptor::addShadowRadiusLocked(Transaction* transaction, int32_t
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 @@ void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction,
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 896bdcc259..6b98b44420 100644
--- a/services/surfaceflinger/SurfaceInterceptor.h
+++ b/services/surfaceflinger/SurfaceInterceptor.h
@@ -168,6 +168,7 @@ private:
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 8fce0c9bf3..2eceba848d 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -105,6 +105,7 @@ LayerProtoParser::Layer LayerProtoParser::generateLayer(const LayerProto& layerP
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 @@ std::string LayerProtoParser::Layer::to_string() const {
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 52b916555f..67bbd76934 100644
--- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
+++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
@@ -109,6 +109,7 @@ public:
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 7f1f542e4b..780b066000 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -123,6 +123,8 @@ message LayerProto {
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 8d97f275ba..5bafbd8975 100644
--- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
+++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
@@ -195,6 +195,7 @@ public:
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 @@ public:
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 @@ void SurfaceInterceptorTest::shadowRadiusUpdate(Transaction& t) {
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 @@ void SurfaceInterceptorTest::runAllUpdates() {
runInTransaction(&SurfaceInterceptorTest::detachChildrenUpdate);
runInTransaction(&SurfaceInterceptorTest::relativeParentUpdate);
runInTransaction(&SurfaceInterceptorTest::shadowRadiusUpdate);
+ runInTransaction(&SurfaceInterceptorTest::trustedOverlayUpdate);
}
void SurfaceInterceptorTest::surfaceCreation(Transaction&) {
@@ -695,6 +702,17 @@ bool SurfaceInterceptorTest::shadowRadiusUpdateFound(const SurfaceChange& change
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 @@ bool SurfaceInterceptorTest::surfaceUpdateFound(const Trace& trace,
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 @@ TEST_F(SurfaceInterceptorTest, InterceptShadowRadiusUpdateWorks) {
SurfaceChange::SurfaceChangeCase::kShadowRadius);
}
+TEST_F(SurfaceInterceptorTest, InterceptTrustedOverlayUpdateWorks) {
+ captureTest(&SurfaceInterceptorTest::trustedOverlayUpdate,
+ SurfaceChange::SurfaceChangeCase::kTrustedOverlay);
+}
+
TEST_F(SurfaceInterceptorTest, InterceptAllUpdatesWorks) {
captureTest(&SurfaceInterceptorTest::runAllUpdates,
&SurfaceInterceptorTest::assertAllUpdatesFound);