Propagate drop input mode correctly to children
We were short circuting updating input info if the layer
did not have an input channel. This prevented us from
propagating the drop input mode correctly.
Fix this by updating all input states that are tied to
parent states as well regardless of input channel.
Test: presbumit (atest LayerSnapshotBuilderTest)
Fixes: 314350323
Change-Id: I955f81aeec1e6eec62f571edb181bbc5a7351385
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index 743cbf3..4e2a25f 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -708,7 +708,7 @@
ftl::Flags<RequestedLayerState::Changes> parentChanges = parentSnapshot.changes &
(RequestedLayerState::Changes::Hierarchy | RequestedLayerState::Changes::Geometry |
RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Metadata |
- RequestedLayerState::Changes::AffectsChildren |
+ RequestedLayerState::Changes::AffectsChildren | RequestedLayerState::Changes::Input |
RequestedLayerState::Changes::FrameRate | RequestedLayerState::Changes::GameMode);
snapshot.changes |= parentChanges;
if (args.displayChanges) snapshot.changes |= RequestedLayerState::Changes::Geometry;
@@ -1035,6 +1035,19 @@
snapshot.inputInfo.id = static_cast<int32_t>(snapshot.uniqueSequence);
snapshot.inputInfo.displayId = static_cast<int32_t>(snapshot.outputFilter.layerStack.id);
+ snapshot.inputInfo.touchOcclusionMode = requested.hasInputInfo()
+ ? requested.windowInfoHandle->getInfo()->touchOcclusionMode
+ : parentSnapshot.inputInfo.touchOcclusionMode;
+ if (requested.dropInputMode == gui::DropInputMode::ALL ||
+ parentSnapshot.dropInputMode == gui::DropInputMode::ALL) {
+ snapshot.dropInputMode = gui::DropInputMode::ALL;
+ } else if (requested.dropInputMode == gui::DropInputMode::OBSCURED ||
+ parentSnapshot.dropInputMode == gui::DropInputMode::OBSCURED) {
+ snapshot.dropInputMode = gui::DropInputMode::OBSCURED;
+ } else {
+ snapshot.dropInputMode = gui::DropInputMode::NONE;
+ }
+
updateVisibility(snapshot, snapshot.isVisible);
if (!needsInputInfo(snapshot, requested)) {
return;
@@ -1058,18 +1071,6 @@
}
snapshot.inputInfo.alpha = snapshot.color.a;
- snapshot.inputInfo.touchOcclusionMode = requested.hasInputInfo()
- ? requested.windowInfoHandle->getInfo()->touchOcclusionMode
- : parentSnapshot.inputInfo.touchOcclusionMode;
- if (requested.dropInputMode == gui::DropInputMode::ALL ||
- parentSnapshot.dropInputMode == gui::DropInputMode::ALL) {
- snapshot.dropInputMode = gui::DropInputMode::ALL;
- } else if (requested.dropInputMode == gui::DropInputMode::OBSCURED ||
- parentSnapshot.dropInputMode == gui::DropInputMode::OBSCURED) {
- snapshot.dropInputMode = gui::DropInputMode::OBSCURED;
- } else {
- snapshot.dropInputMode = gui::DropInputMode::NONE;
- }
handleDropInputMode(snapshot, parentSnapshot);
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index b1a18ae..1991be4 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -417,6 +417,8 @@
if (!obj.handleAlive) out << " handleNotAlive";
if (obj.requestedFrameRate.isValid())
out << " requestedFrameRate: {" << obj.requestedFrameRate << "}";
+ if (obj.dropInputMode != gui::DropInputMode::NONE)
+ out << " dropInputMode=" << static_cast<uint32_t>(obj.dropInputMode);
return out;
}
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index 48f8923..7e9abce 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -478,6 +478,17 @@
mLifecycleManager.applyTransactions(transactions);
}
+ void setDropInputMode(uint32_t id, gui::DropInputMode dropInputMode) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eDropInputModeChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.dropInputMode = dropInputMode;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
LayerLifecycleManager mLifecycleManager;
};
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index 16143e3..375aa41 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -1074,4 +1074,25 @@
EXPECT_TRUE(getSnapshot(11)->isSecure);
}
+// b/314350323
+TEST_F(LayerSnapshotTest, propagateDropInputMode) {
+ setDropInputMode(1, gui::DropInputMode::ALL);
+ LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(),
+ .layerLifecycleManager = mLifecycleManager,
+ .includeMetadata = false,
+ .displays = mFrontEndDisplayInfos,
+ .displayChanges = false,
+ .globalShadowSettings = globalShadowSettings,
+ .supportsBlur = true,
+ .supportedLayerGenericMetadata = {},
+ .genericLayerMetadataKeyMap = {}};
+ args.rootSnapshot.isSecure = true;
+ update(mSnapshotBuilder, args);
+
+ EXPECT_EQ(getSnapshot(1)->dropInputMode, gui::DropInputMode::ALL);
+ // Ensure child also has the correct drop input mode regardless of whether either layer has
+ // an input channel
+ EXPECT_EQ(getSnapshot(11)->dropInputMode, gui::DropInputMode::ALL);
+}
+
} // namespace android::surfaceflinger::frontend