Loading services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +30 −10 Original line number Diff line number Diff line Loading @@ -313,6 +313,21 @@ void updateMetadata(LayerSnapshot& snapshot, const RequestedLayerState& requeste } } void updateMetadataAndGameMode(LayerSnapshot& snapshot, const RequestedLayerState& requested, const LayerSnapshotBuilder::Args& args, const LayerSnapshot& parentSnapshot) { if (snapshot.changes.test(RequestedLayerState::Changes::GameMode)) { snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE) ? requested.gameMode : parentSnapshot.gameMode; } updateMetadata(snapshot, requested, args); if (args.includeMetadata) { snapshot.layerMetadata = parentSnapshot.layerMetadata; snapshot.layerMetadata.merge(requested.metadata); } } void clearChanges(LayerSnapshot& snapshot) { snapshot.changes.clear(); snapshot.clientChanges = 0; Loading Loading @@ -746,6 +761,11 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a RequestedLayerState::Changes::Input)) { updateInput(snapshot, requested, parentSnapshot, path, args); } if (forceUpdate || (args.includeMetadata && snapshot.changes.test(RequestedLayerState::Changes::Metadata))) { updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot); } return; } Loading Loading @@ -786,16 +806,7 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a } if (forceUpdate || snapshot.changes.test(RequestedLayerState::Changes::Metadata)) { if (snapshot.changes.test(RequestedLayerState::Changes::GameMode)) { snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE) ? requested.gameMode : parentSnapshot.gameMode; } updateMetadata(snapshot, requested, args); if (args.includeMetadata) { snapshot.layerMetadata = parentSnapshot.layerMetadata; snapshot.layerMetadata.merge(requested.metadata); } updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot); } if (forceUpdate || snapshot.clientChanges & layer_state_t::eFixedTransformHintChanged || Loading Loading @@ -1164,6 +1175,15 @@ void LayerSnapshotBuilder::forEachVisibleSnapshot(const Visitor& visitor) { } } void LayerSnapshotBuilder::forEachSnapshot(const Visitor& visitor, const ConstPredicate& predicate) { for (int i = 0; i < mNumInterestingSnapshots; i++) { std::unique_ptr<LayerSnapshot>& snapshot = mSnapshots.at((size_t)i); if (!predicate(*snapshot)) continue; visitor(snapshot); } } void LayerSnapshotBuilder::forEachInputSnapshot(const ConstVisitor& visitor) const { for (int i = mNumInterestingSnapshots - 1; i >= 0; i--) { LayerSnapshot& snapshot = *mSnapshots[(size_t)i]; Loading services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h +5 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,11 @@ public: // Visit each visible snapshot in z-order and move the snapshot if needed void forEachVisibleSnapshot(const Visitor& visitor); typedef std::function<bool(const LayerSnapshot& snapshot)> ConstPredicate; // Visit each snapshot that satisfies the predicate and move the snapshot if needed with visible // snapshots in z-order void forEachSnapshot(const Visitor& visitor, const ConstPredicate& predicate); // Visit each snapshot interesting to input reverse z-order void forEachInputSnapshot(const ConstVisitor& visitor) const; Loading services/surfaceflinger/SurfaceFlinger.cpp +9 −1 Original line number Diff line number Diff line Loading @@ -9239,7 +9239,9 @@ std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToComposit std::vector<std::pair<Layer*, LayerFE*>> layers; if (mLayerLifecycleManagerEnabled) { nsecs_t currentTime = systemTime(); mLayerSnapshotBuilder.forEachVisibleSnapshot( const bool needsMetadata = mCompositionEngine->getFeatureFlags().test( compositionengine::Feature::kSnapshotLayerMetadata); mLayerSnapshotBuilder.forEachSnapshot( [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD( kMainThreadContext) { if (cursorOnly && Loading @@ -9262,6 +9264,12 @@ std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToComposit layerFE->mSnapshot = std::move(snapshot); refreshArgs.layers.push_back(layerFE); layers.emplace_back(legacyLayer.get(), layerFE.get()); }, [needsMetadata](const frontend::LayerSnapshot& snapshot) { return snapshot.isVisible || (needsMetadata && snapshot.changes.test( frontend::RequestedLayerState::Changes::Metadata)); }); } if (!mLayerLifecycleManagerEnabled) { Loading services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp +60 −0 Original line number Diff line number Diff line Loading @@ -333,6 +333,55 @@ TEST_F(LayerSnapshotTest, UpdateMetadata) { EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_CALLING_UID, -1), 789); } TEST_F(LayerSnapshotTest, UpdateMetadataOfHiddenLayers) { hideLayer(1); std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eMetadataChanged; // This test focuses on metadata used by ARC++ to ensure LayerMetadata is updated correctly, // and not using stale data. transactions.back().states.front().state.metadata = LayerMetadata(); transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_UID, 123); transactions.back().states.front().state.metadata.setInt32(METADATA_WINDOW_TYPE, 234); transactions.back().states.front().state.metadata.setInt32(METADATA_TASK_ID, 345); transactions.back().states.front().state.metadata.setInt32(METADATA_MOUSE_CURSOR, 456); transactions.back().states.front().state.metadata.setInt32(METADATA_ACCESSIBILITY_ID, 567); transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_PID, 678); transactions.back().states.front().state.metadata.setInt32(METADATA_CALLING_UID, 789); transactions.back().states.front().layerId = 1; transactions.back().states.front().state.layerId = static_cast<int32_t>(1); mLifecycleManager.applyTransactions(transactions); EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::Metadata | RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::VisibleRegion | RequestedLayerState::Changes::AffectsChildren); // Setting includeMetadata=true to ensure metadata update is applied to LayerSnapshot LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(), .layerLifecycleManager = mLifecycleManager, .includeMetadata = true, .displays = mFrontEndDisplayInfos, .globalShadowSettings = globalShadowSettings, .supportsBlur = true, .supportedLayerGenericMetadata = {}, .genericLayerMetadataKeyMap = {}}; update(mSnapshotBuilder, args); EXPECT_EQ(static_cast<int64_t>(getSnapshot(1)->clientChanges), layer_state_t::eMetadataChanged | layer_state_t::eFlagsChanged); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_UID, -1), 123); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_WINDOW_TYPE, -1), 234); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_TASK_ID, -1), 345); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_MOUSE_CURSOR, -1), 456); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_ACCESSIBILITY_ID, -1), 567); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_PID, -1), 678); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_CALLING_UID, -1), 789); } TEST_F(LayerSnapshotTest, NoLayerVoteForParentWithChildVotes) { // ROOT // ├── 1 Loading Loading @@ -1329,6 +1378,17 @@ TEST_F(LayerSnapshotTest, NonVisibleLayerWithInput) { EXPECT_TRUE(foundInputLayer); } TEST_F(LayerSnapshotTest, ForEachSnapshotsWithPredicate) { std::vector<uint32_t> visitedUniqueSequences; mSnapshotBuilder.forEachSnapshot( [&](const std::unique_ptr<frontend::LayerSnapshot>& snapshot) { visitedUniqueSequences.push_back(snapshot->uniqueSequence); }, [](const frontend::LayerSnapshot& snapshot) { return snapshot.uniqueSequence == 111; }); EXPECT_EQ(visitedUniqueSequences.size(), 1u); EXPECT_EQ(visitedUniqueSequences[0], 111u); } TEST_F(LayerSnapshotTest, canOccludePresentation) { setFlags(12, layer_state_t::eCanOccludePresentation, layer_state_t::eCanOccludePresentation); LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(), Loading Loading
services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +30 −10 Original line number Diff line number Diff line Loading @@ -313,6 +313,21 @@ void updateMetadata(LayerSnapshot& snapshot, const RequestedLayerState& requeste } } void updateMetadataAndGameMode(LayerSnapshot& snapshot, const RequestedLayerState& requested, const LayerSnapshotBuilder::Args& args, const LayerSnapshot& parentSnapshot) { if (snapshot.changes.test(RequestedLayerState::Changes::GameMode)) { snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE) ? requested.gameMode : parentSnapshot.gameMode; } updateMetadata(snapshot, requested, args); if (args.includeMetadata) { snapshot.layerMetadata = parentSnapshot.layerMetadata; snapshot.layerMetadata.merge(requested.metadata); } } void clearChanges(LayerSnapshot& snapshot) { snapshot.changes.clear(); snapshot.clientChanges = 0; Loading Loading @@ -746,6 +761,11 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a RequestedLayerState::Changes::Input)) { updateInput(snapshot, requested, parentSnapshot, path, args); } if (forceUpdate || (args.includeMetadata && snapshot.changes.test(RequestedLayerState::Changes::Metadata))) { updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot); } return; } Loading Loading @@ -786,16 +806,7 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a } if (forceUpdate || snapshot.changes.test(RequestedLayerState::Changes::Metadata)) { if (snapshot.changes.test(RequestedLayerState::Changes::GameMode)) { snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE) ? requested.gameMode : parentSnapshot.gameMode; } updateMetadata(snapshot, requested, args); if (args.includeMetadata) { snapshot.layerMetadata = parentSnapshot.layerMetadata; snapshot.layerMetadata.merge(requested.metadata); } updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot); } if (forceUpdate || snapshot.clientChanges & layer_state_t::eFixedTransformHintChanged || Loading Loading @@ -1164,6 +1175,15 @@ void LayerSnapshotBuilder::forEachVisibleSnapshot(const Visitor& visitor) { } } void LayerSnapshotBuilder::forEachSnapshot(const Visitor& visitor, const ConstPredicate& predicate) { for (int i = 0; i < mNumInterestingSnapshots; i++) { std::unique_ptr<LayerSnapshot>& snapshot = mSnapshots.at((size_t)i); if (!predicate(*snapshot)) continue; visitor(snapshot); } } void LayerSnapshotBuilder::forEachInputSnapshot(const ConstVisitor& visitor) const { for (int i = mNumInterestingSnapshots - 1; i >= 0; i--) { LayerSnapshot& snapshot = *mSnapshots[(size_t)i]; Loading
services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h +5 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,11 @@ public: // Visit each visible snapshot in z-order and move the snapshot if needed void forEachVisibleSnapshot(const Visitor& visitor); typedef std::function<bool(const LayerSnapshot& snapshot)> ConstPredicate; // Visit each snapshot that satisfies the predicate and move the snapshot if needed with visible // snapshots in z-order void forEachSnapshot(const Visitor& visitor, const ConstPredicate& predicate); // Visit each snapshot interesting to input reverse z-order void forEachInputSnapshot(const ConstVisitor& visitor) const; Loading
services/surfaceflinger/SurfaceFlinger.cpp +9 −1 Original line number Diff line number Diff line Loading @@ -9239,7 +9239,9 @@ std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToComposit std::vector<std::pair<Layer*, LayerFE*>> layers; if (mLayerLifecycleManagerEnabled) { nsecs_t currentTime = systemTime(); mLayerSnapshotBuilder.forEachVisibleSnapshot( const bool needsMetadata = mCompositionEngine->getFeatureFlags().test( compositionengine::Feature::kSnapshotLayerMetadata); mLayerSnapshotBuilder.forEachSnapshot( [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD( kMainThreadContext) { if (cursorOnly && Loading @@ -9262,6 +9264,12 @@ std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToComposit layerFE->mSnapshot = std::move(snapshot); refreshArgs.layers.push_back(layerFE); layers.emplace_back(legacyLayer.get(), layerFE.get()); }, [needsMetadata](const frontend::LayerSnapshot& snapshot) { return snapshot.isVisible || (needsMetadata && snapshot.changes.test( frontend::RequestedLayerState::Changes::Metadata)); }); } if (!mLayerLifecycleManagerEnabled) { Loading
services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp +60 −0 Original line number Diff line number Diff line Loading @@ -333,6 +333,55 @@ TEST_F(LayerSnapshotTest, UpdateMetadata) { EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_CALLING_UID, -1), 789); } TEST_F(LayerSnapshotTest, UpdateMetadataOfHiddenLayers) { hideLayer(1); std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eMetadataChanged; // This test focuses on metadata used by ARC++ to ensure LayerMetadata is updated correctly, // and not using stale data. transactions.back().states.front().state.metadata = LayerMetadata(); transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_UID, 123); transactions.back().states.front().state.metadata.setInt32(METADATA_WINDOW_TYPE, 234); transactions.back().states.front().state.metadata.setInt32(METADATA_TASK_ID, 345); transactions.back().states.front().state.metadata.setInt32(METADATA_MOUSE_CURSOR, 456); transactions.back().states.front().state.metadata.setInt32(METADATA_ACCESSIBILITY_ID, 567); transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_PID, 678); transactions.back().states.front().state.metadata.setInt32(METADATA_CALLING_UID, 789); transactions.back().states.front().layerId = 1; transactions.back().states.front().state.layerId = static_cast<int32_t>(1); mLifecycleManager.applyTransactions(transactions); EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::Metadata | RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::VisibleRegion | RequestedLayerState::Changes::AffectsChildren); // Setting includeMetadata=true to ensure metadata update is applied to LayerSnapshot LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(), .layerLifecycleManager = mLifecycleManager, .includeMetadata = true, .displays = mFrontEndDisplayInfos, .globalShadowSettings = globalShadowSettings, .supportsBlur = true, .supportedLayerGenericMetadata = {}, .genericLayerMetadataKeyMap = {}}; update(mSnapshotBuilder, args); EXPECT_EQ(static_cast<int64_t>(getSnapshot(1)->clientChanges), layer_state_t::eMetadataChanged | layer_state_t::eFlagsChanged); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_UID, -1), 123); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_WINDOW_TYPE, -1), 234); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_TASK_ID, -1), 345); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_MOUSE_CURSOR, -1), 456); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_ACCESSIBILITY_ID, -1), 567); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_PID, -1), 678); EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_CALLING_UID, -1), 789); } TEST_F(LayerSnapshotTest, NoLayerVoteForParentWithChildVotes) { // ROOT // ├── 1 Loading Loading @@ -1329,6 +1378,17 @@ TEST_F(LayerSnapshotTest, NonVisibleLayerWithInput) { EXPECT_TRUE(foundInputLayer); } TEST_F(LayerSnapshotTest, ForEachSnapshotsWithPredicate) { std::vector<uint32_t> visitedUniqueSequences; mSnapshotBuilder.forEachSnapshot( [&](const std::unique_ptr<frontend::LayerSnapshot>& snapshot) { visitedUniqueSequences.push_back(snapshot->uniqueSequence); }, [](const frontend::LayerSnapshot& snapshot) { return snapshot.uniqueSequence == 111; }); EXPECT_EQ(visitedUniqueSequences.size(), 1u); EXPECT_EQ(visitedUniqueSequences[0], 111u); } TEST_F(LayerSnapshotTest, canOccludePresentation) { setFlags(12, layer_state_t::eCanOccludePresentation, layer_state_t::eCanOccludePresentation); LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(), Loading