Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8eb8f35c authored by Garfield Tan's avatar Garfield Tan
Browse files

SF: Update metadata of unvisible layers to backend

ARC++ relies on metadata to convey a variety of information, including
window states through a in-house metadata. Some of them may change when
a layer is invisible, and ARC++ backend needs to respond to these
changes immediately. Such case may happen when user minimizes a window.

Bug: 340946541
Test: Minimize on ARC++.
Test: atest libsurfaceflinger_unittest
Change-Id: Ie384cc8bd672a8277ef9437f908a6f969e422aee
parent 2088c4f9
Loading
Loading
Loading
Loading
+30 −10
Original line number Diff line number Diff line
@@ -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;
@@ -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;
    }

@@ -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 ||
@@ -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];
+5 −0
Original line number Diff line number Diff line
@@ -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;

+9 −1
Original line number Diff line number Diff line
@@ -9233,7 +9233,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 &&
@@ -9256,6 +9258,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) {
+60 −0
Original line number Diff line number Diff line
@@ -329,6 +329,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
@@ -1325,6 +1374,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(),