SF: Frontend fixes for issues surfaced by SurfaceFlinger_test

- separate color and bgcolor in layer state so we don't set a color
 on a layer without a buffer
 - avoid using legacy layer state when latching a buffer
 - fix callback issue where invisible or offscreen layers were not invoking
 the callbacks
 - pass in layer snapshot for trusted presentation state
 - fix a screenshot issue where the root layer was skipped
 - pass in framerate changes to layer history

Test: presubmit
Test: atest SurfaceFlinger_test with new fe
Bug: 238781169

Change-Id: Id9ff8a036dc283e21a05985c1c01ebd070b1df24
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
index 0b4d20c..eae5871 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
@@ -213,9 +213,7 @@
     float currentSdrHdrRatio = 1.f;
     float desiredSdrHdrRatio = 1.f;
 
-    bool isInternalDisplayOverlay = false;
     gui::CachingHint cachingHint = gui::CachingHint::Enabled;
-
     virtual ~LayerFECompositionState();
 
     // Debugging
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 7d94316..175dd1d 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -538,8 +538,8 @@
         return;
     }
 
-    bool computeAboveCoveredExcludingOverlays =
-            coverage.aboveCoveredLayersExcludingOverlays && !layerFEState->isInternalDisplayOverlay;
+    bool computeAboveCoveredExcludingOverlays = coverage.aboveCoveredLayersExcludingOverlays &&
+            !layerFEState->outputFilter.toInternalDisplay;
 
     /*
      * opaqueRegion: area of a surface that is fully opaque.
diff --git a/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp b/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp
index 6d492c0..6659825 100644
--- a/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp
@@ -24,9 +24,13 @@
 
 std::atomic<uint32_t> LayerCreationArgs::sSequence{1};
 
+uint32_t LayerCreationArgs::getInternalLayerId(uint32_t id) {
+    return id | INTERNAL_LAYER_PREFIX;
+}
+
 LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp<Client> client, std::string name,
                                      uint32_t flags, gui::LayerMetadata metadataArg,
-                                     std::optional<uint32_t> id)
+                                     std::optional<uint32_t> id, bool internalLayer)
       : flinger(flinger),
         client(std::move(client)),
         name(std::move(name)),
@@ -46,10 +50,15 @@
 
     if (id) {
         sequence = *id;
-        sSequence = *id + 1;
+        if (internalLayer) {
+            sequence = getInternalLayerId(*id);
+        } else {
+            sSequence = *id + 1;
+        }
     } else {
         sequence = sSequence++;
-        if (sequence == UNASSIGNED_LAYER_ID) {
+        if (sequence >= INTERNAL_LAYER_PREFIX) {
+            sSequence = 1;
             ALOGW("Layer sequence id rolled over.");
             sequence = sSequence++;
         }
diff --git a/services/surfaceflinger/FrontEnd/LayerCreationArgs.h b/services/surfaceflinger/FrontEnd/LayerCreationArgs.h
index 9d2aaab..2cd6b55 100644
--- a/services/surfaceflinger/FrontEnd/LayerCreationArgs.h
+++ b/services/surfaceflinger/FrontEnd/LayerCreationArgs.h
@@ -25,6 +25,7 @@
 #include <optional>
 
 constexpr uint32_t UNASSIGNED_LAYER_ID = std::numeric_limits<uint32_t>::max();
+constexpr uint32_t INTERNAL_LAYER_PREFIX = 1u << 31;
 
 namespace android {
 class SurfaceFlinger;
@@ -35,10 +36,11 @@
 
 struct LayerCreationArgs {
     static std::atomic<uint32_t> sSequence;
+    static uint32_t getInternalLayerId(uint32_t id);
 
     LayerCreationArgs(android::SurfaceFlinger*, sp<android::Client>, std::string name,
-                      uint32_t flags, gui::LayerMetadata,
-                      std::optional<uint32_t> id = std::nullopt);
+                      uint32_t flags, gui::LayerMetadata, std::optional<uint32_t> id = std::nullopt,
+                      bool internalLayer = false);
     LayerCreationArgs(const LayerCreationArgs&);
 
     android::SurfaceFlinger* flinger;
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.h b/services/surfaceflinger/FrontEnd/LayerHierarchy.h
index 2ab897b..0f700a9 100644
--- a/services/surfaceflinger/FrontEnd/LayerHierarchy.h
+++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.h
@@ -128,12 +128,18 @@
     // Traverse the hierarchy and visit all child variants.
     void traverse(const Visitor& visitor) const {
         TraversalPath root = TraversalPath::ROOT;
+        if (mLayer) {
+            root.id = mLayer->id;
+        }
         traverse(visitor, root);
     }
 
     // Traverse the hierarchy in z-order, skipping children that have relative parents.
     void traverseInZOrder(const Visitor& visitor) const {
         TraversalPath root = TraversalPath::ROOT;
+        if (mLayer) {
+            root.id = mLayer->id;
+        }
         traverseInZOrder(visitor, root);
     }
 
diff --git a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
index 66197be..79ffcbf 100644
--- a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
@@ -192,35 +192,38 @@
             layer->merge(resolvedComposerState);
 
             if (layer->what & layer_state_t::eBackgroundColorChanged) {
-                if (layer->bgColorLayerId == UNASSIGNED_LAYER_ID && layer->bgColorAlpha != 0) {
+                if (layer->bgColorLayerId == UNASSIGNED_LAYER_ID && layer->bgColor.a != 0) {
                     LayerCreationArgs backgroundLayerArgs{nullptr,
                                                           nullptr,
                                                           layer->name + "BackgroundColorLayer",
                                                           ISurfaceComposerClient::eFXSurfaceEffect,
-                                                          {}};
+                                                          {},
+                                                          layer->id,
+                                                          /*internalLayer=*/true};
                     std::vector<std::unique_ptr<RequestedLayerState>> newLayers;
                     newLayers.emplace_back(
                             std::make_unique<RequestedLayerState>(backgroundLayerArgs));
                     RequestedLayerState* backgroundLayer = newLayers.back().get();
+                    backgroundLayer->bgColorLayer = true;
                     backgroundLayer->handleAlive = false;
                     backgroundLayer->parentId = layer->id;
                     backgroundLayer->z = std::numeric_limits<int32_t>::min();
-                    backgroundLayer->color.rgb = layer->color.rgb;
-                    backgroundLayer->color.a = layer->bgColorAlpha;
+                    backgroundLayer->color = layer->bgColor;
                     backgroundLayer->dataspace = layer->bgColorDataspace;
-
                     layer->bgColorLayerId = backgroundLayer->id;
                     addLayers({std::move(newLayers)});
-                } else if (layer->bgColorLayerId != UNASSIGNED_LAYER_ID &&
-                           layer->bgColorAlpha == 0) {
+                } else if (layer->bgColorLayerId != UNASSIGNED_LAYER_ID && layer->bgColor.a == 0) {
                     RequestedLayerState* bgColorLayer = getLayerFromId(layer->bgColorLayerId);
-                    bgColorLayer->parentId = UNASSIGNED_LAYER_ID;
-                    onHandlesDestroyed({layer->bgColorLayerId});
+                    layer->bgColorLayerId = UNASSIGNED_LAYER_ID;
+                    bgColorLayer->parentId = unlinkLayer(bgColorLayer->parentId, bgColorLayer->id);
+                    onHandlesDestroyed({bgColorLayer->id});
                 } else if (layer->bgColorLayerId != UNASSIGNED_LAYER_ID) {
                     RequestedLayerState* bgColorLayer = getLayerFromId(layer->bgColorLayerId);
-                    bgColorLayer->color.rgb = layer->color.rgb;
-                    bgColorLayer->color.a = layer->bgColorAlpha;
+                    bgColorLayer->color = layer->bgColor;
                     bgColorLayer->dataspace = layer->bgColorDataspace;
+                    bgColorLayer->what |= layer_state_t::eColorChanged |
+                            layer_state_t::eDataspaceChanged | layer_state_t::eAlphaChanged;
+                    bgColorLayer->changes |= RequestedLayerState::Changes::Content;
                     mGlobalChanges |= RequestedLayerState::Changes::Content;
                 }
             }
@@ -256,8 +259,7 @@
                 listener->onLayerAdded(*layer);
             }
         }
-        layer->what = 0;
-        layer->changes.clear();
+        layer->clearChanges();
     }
 
     for (auto& destroyedLayer : mDestroyedLayers) {
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
index dbb7fbf..f866175 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
@@ -139,7 +139,8 @@
     // visible
     std::stringstream reason;
     if (sidebandStream != nullptr) reason << " sidebandStream";
-    if (externalTexture != nullptr) reason << " buffer";
+    if (externalTexture != nullptr)
+        reason << " buffer:" << externalTexture->getId() << " frame:" << frameNumber;
     if (fillsColor() || color.a > 0.0f) reason << " color{" << color << "}";
     if (drawShadows()) reason << " shadowSettings.length=" << shadowSettings.length;
     if (backgroundBlurRadius > 0) reason << " backgroundBlurRadius=" << backgroundBlurRadius;
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index d740350..c7f9aa7 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -337,12 +337,12 @@
 LayerSnapshotBuilder::LayerSnapshotBuilder() : mRootSnapshot(getRootSnapshot()) {}
 
 LayerSnapshotBuilder::LayerSnapshotBuilder(Args args) : LayerSnapshotBuilder() {
-    args.forceUpdate = true;
+    args.forceUpdate = ForceUpdateFlags::ALL;
     updateSnapshots(args);
 }
 
 bool LayerSnapshotBuilder::tryFastUpdate(const Args& args) {
-    if (args.forceUpdate || args.displayChanges) {
+    if (args.forceUpdate != ForceUpdateFlags::NONE || args.displayChanges) {
         // force update requested, or we have display changes, so skip the fast path
         return false;
     }
@@ -393,19 +393,31 @@
     ATRACE_NAME("UpdateSnapshots");
     if (args.parentCrop) {
         mRootSnapshot.geomLayerBounds = *args.parentCrop;
-    } else if (args.forceUpdate || args.displayChanges) {
+    } else if (args.forceUpdate == ForceUpdateFlags::ALL || args.displayChanges) {
         mRootSnapshot.geomLayerBounds = getMaxDisplayBounds(args.displays);
     }
     if (args.displayChanges) {
         mRootSnapshot.changes = RequestedLayerState::Changes::AffectsChildren |
                 RequestedLayerState::Changes::Geometry;
     }
+    if (args.forceUpdate == ForceUpdateFlags::HIERARCHY) {
+        mRootSnapshot.changes |=
+                RequestedLayerState::Changes::Hierarchy | RequestedLayerState::Changes::Visibility;
+    }
     LayerHierarchy::TraversalPath root = LayerHierarchy::TraversalPath::ROOT;
-    for (auto& [childHierarchy, variant] : args.root.mChildren) {
-        LayerHierarchy::ScopedAddToTraversalPath addChildToPath(root,
-                                                                childHierarchy->getLayer()->id,
-                                                                variant);
-        updateSnapshotsInHierarchy(args, *childHierarchy, root, mRootSnapshot);
+    if (args.root.getLayer()) {
+        // The hierarchy can have a root layer when used for screenshots otherwise, it will have
+        // multiple children.
+        LayerHierarchy::ScopedAddToTraversalPath addChildToPath(root, args.root.getLayer()->id,
+                                                                LayerHierarchy::Variant::Attached);
+        updateSnapshotsInHierarchy(args, args.root, root, mRootSnapshot);
+    } else {
+        for (auto& [childHierarchy, variant] : args.root.mChildren) {
+            LayerHierarchy::ScopedAddToTraversalPath addChildToPath(root,
+                                                                    childHierarchy->getLayer()->id,
+                                                                    variant);
+            updateSnapshotsInHierarchy(args, *childHierarchy, root, mRootSnapshot);
+        }
     }
 
     sortSnapshotsByZ(args);
@@ -451,6 +463,7 @@
     if (newSnapshot) {
         snapshot = createSnapshot(traversalPath, *layer);
     }
+    scheduler::LayerInfo::FrameRate oldFrameRate = snapshot->frameRate;
     if (traversalPath.isRelative()) {
         bool parentIsRelative = traversalPath.variant == LayerHierarchy::Variant::Relative;
         updateRelativeState(*snapshot, parentSnapshot, parentIsRelative, args);
@@ -469,6 +482,10 @@
                 updateSnapshotsInHierarchy(args, *childHierarchy, traversalPath, *snapshot);
         updateChildState(*snapshot, childSnapshot, args);
     }
+
+    if (oldFrameRate == snapshot->frameRate) {
+        snapshot->changes.clear(RequestedLayerState::Changes::FrameRate);
+    }
     return *snapshot;
 }
 
@@ -495,7 +512,7 @@
 }
 
 void LayerSnapshotBuilder::sortSnapshotsByZ(const Args& args) {
-    if (!mResortSnapshots && !args.forceUpdate &&
+    if (!mResortSnapshots && args.forceUpdate == ForceUpdateFlags::NONE &&
         !args.layerLifecycleManager.getGlobalChanges().any(
                 RequestedLayerState::Changes::Hierarchy |
                 RequestedLayerState::Changes::Visibility)) {
@@ -569,7 +586,8 @@
     if (snapshot.childState.hasValidFrameRate) {
         return;
     }
-    if (args.forceUpdate || childSnapshot.changes.test(RequestedLayerState::Changes::FrameRate)) {
+    if (args.forceUpdate == ForceUpdateFlags::ALL ||
+        childSnapshot.changes.test(RequestedLayerState::Changes::FrameRate)) {
         // We return whether this layer ot its children has a vote. We ignore ExactOrMultiple votes
         // for the same reason we are allowing touch boost for those layers. See
         // RefreshRateSelector::rankFrameRates for details.
@@ -618,21 +636,20 @@
     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::FrameRate);
     snapshot.changes = parentChanges | requested.changes;
     snapshot.isHiddenByPolicyFromParent = parentSnapshot.isHiddenByPolicyFromParent ||
             parentSnapshot.invalidTransform || requested.isHiddenByPolicy() ||
             (args.excludeLayerIds.find(path.id) != args.excludeLayerIds.end());
     snapshot.contentDirty = requested.what & layer_state_t::CONTENT_DIRTY;
     // TODO(b/238781169) scope down the changes to only buffer updates.
-    snapshot.hasReadyFrame =
-            (snapshot.contentDirty || requested.autoRefresh) && (requested.externalTexture);
-    // TODO(b/238781169) how is this used? ag/15523870
-    snapshot.sidebandStreamHasFrame = false;
+    snapshot.hasReadyFrame = requested.hasReadyFrame();
+    snapshot.sidebandStreamHasFrame = requested.hasSidebandStreamFrame();
     updateSurfaceDamage(requested, snapshot.hasReadyFrame, args.forceFullDamage,
                         snapshot.surfaceDamage);
 
-    const bool forceUpdate = newSnapshot || args.forceUpdate ||
+    const bool forceUpdate = newSnapshot || args.forceUpdate == ForceUpdateFlags::ALL ||
             snapshot.changes.any(RequestedLayerState::Changes::Visibility |
                                  RequestedLayerState::Changes::Created);
     snapshot.outputFilter.layerStack = requested.parentId != UNASSIGNED_LAYER_ID
@@ -708,11 +725,6 @@
         snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE)
                 ? requested.gameMode
                 : parentSnapshot.gameMode;
-        snapshot.frameRate = (requested.requestedFrameRate.rate.isValid() ||
-                              (requested.requestedFrameRate.type ==
-                               scheduler::LayerInfo::FrameRateCompatibility::NoVote))
-                ? requested.requestedFrameRate
-                : parentSnapshot.frameRate;
         snapshot.fixedTransformHint = requested.fixedTransformHint != ui::Transform::ROT_INVALID
                 ? requested.fixedTransformHint
                 : parentSnapshot.fixedTransformHint;
@@ -722,6 +734,16 @@
                 (requested.layerStackToMirror != ui::INVALID_LAYER_STACK);
     }
 
+    if (forceUpdate ||
+        snapshot.changes.any(RequestedLayerState::Changes::FrameRate |
+                             RequestedLayerState::Changes::Hierarchy)) {
+        snapshot.frameRate = (requested.requestedFrameRate.rate.isValid() ||
+                              (requested.requestedFrameRate.type ==
+                               scheduler::LayerInfo::FrameRateCompatibility::NoVote))
+                ? requested.requestedFrameRate
+                : parentSnapshot.frameRate;
+    }
+
     if (forceUpdate || requested.changes.get() != 0) {
         snapshot.compositionType = requested.getCompositionType();
         snapshot.dimmingEnabled = requested.dimmingEnabled;
@@ -773,10 +795,11 @@
     // snapshot.metadata;
     LLOGV(snapshot.sequence,
           "%supdated [%d]%s changes parent:%s global:%s local:%s requested:%s %s from parent %s",
-          args.forceUpdate ? "Force " : "", requested.id, requested.name.c_str(),
-          parentSnapshot.changes.string().c_str(), snapshot.changes.string().c_str(),
-          requested.changes.string().c_str(), std::to_string(requested.what).c_str(),
-          snapshot.getDebugString().c_str(), parentSnapshot.getDebugString().c_str());
+          args.forceUpdate == ForceUpdateFlags::ALL ? "Force " : "", requested.id,
+          requested.name.c_str(), parentSnapshot.changes.string().c_str(),
+          snapshot.changes.string().c_str(), requested.changes.string().c_str(),
+          std::to_string(requested.what).c_str(), snapshot.getDebugString().c_str(),
+          parentSnapshot.getDebugString().c_str());
 }
 
 void LayerSnapshotBuilder::updateRoundedCorner(LayerSnapshot& snapshot,
@@ -912,8 +935,12 @@
     } else {
         snapshot.inputInfo = {};
     }
-    snapshot.inputInfo.displayId = static_cast<int32_t>(snapshot.outputFilter.layerStack.id);
 
+    snapshot.inputInfo.name = requested.name;
+    snapshot.inputInfo.id = static_cast<int32_t>(requested.id);
+    snapshot.inputInfo.ownerUid = static_cast<int32_t>(requested.ownerUid);
+    snapshot.inputInfo.ownerPid = requested.ownerPid;
+    snapshot.inputInfo.displayId = static_cast<int32_t>(snapshot.outputFilter.layerStack.id);
     if (!needsInputInfo(snapshot, requested)) {
         return;
     }
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
index 0902ab8..d70bdb9 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
@@ -35,10 +35,15 @@
 // snapshots when there are only buffer updates.
 class LayerSnapshotBuilder {
 public:
+    enum class ForceUpdateFlags {
+        NONE,
+        ALL,
+        HIERARCHY,
+    };
     struct Args {
         LayerHierarchy root;
         const LayerLifecycleManager& layerLifecycleManager;
-        bool forceUpdate = false;
+        ForceUpdateFlags forceUpdate = ForceUpdateFlags::NONE;
         bool includeMetadata = false;
         const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displays;
         // Set to true if there were display changes since last update.
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index 09523d3..e2cbe28 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -165,8 +165,13 @@
         if (hadBufferOrSideStream != hasBufferOrSideStream) {
             changes |= RequestedLayerState::Changes::Geometry |
                     RequestedLayerState::Changes::VisibleRegion |
-                    RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Input |
-                    RequestedLayerState::Changes::Buffer;
+                    RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Input;
+        }
+        if (clientState.what & layer_state_t::eBufferChanged) {
+            changes |= RequestedLayerState::Changes::Buffer;
+        }
+        if (clientState.what & layer_state_t::eSidebandStreamChanged) {
+            changes |= RequestedLayerState::Changes::SidebandStream;
         }
     }
     if (what & (layer_state_t::eAlphaChanged)) {
@@ -197,7 +202,9 @@
         static const mat4 identityMatrix = mat4();
         hasColorTransform = colorTransform != identityMatrix;
     }
-    if (clientState.what & (layer_state_t::eLayerChanged | layer_state_t::eRelativeLayerChanged)) {
+    if (clientState.what &
+        (layer_state_t::eLayerChanged | layer_state_t::eRelativeLayerChanged |
+         layer_state_t::eLayerStackChanged)) {
         changes |= RequestedLayerState::Changes::Z;
     }
     if (clientState.what & layer_state_t::eReparent) {
@@ -453,4 +460,22 @@
     return backgroundBlurRadius > 0 || blurRegions.size() > 0;
 }
 
+bool RequestedLayerState::hasFrameUpdate() const {
+    return what & layer_state_t::CONTENT_DIRTY &&
+            (externalTexture || bgColorLayerId != UNASSIGNED_LAYER_ID);
+}
+
+bool RequestedLayerState::hasReadyFrame() const {
+    return hasFrameUpdate() || changes.test(Changes::SidebandStream) || autoRefresh;
+}
+
+bool RequestedLayerState::hasSidebandStreamFrame() const {
+    return hasFrameUpdate() && sidebandStream.get();
+}
+
+void RequestedLayerState::clearChanges() {
+    what = 0;
+    changes.clear();
+}
+
 } // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.h b/services/surfaceflinger/FrontEnd/RequestedLayerState.h
index 6840b25..8b475a3 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.h
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.h
@@ -52,10 +52,13 @@
         FrameRate = 1u << 13,
         VisibleRegion = 1u << 14,
         Buffer = 1u << 15,
+        SidebandStream = 1u << 16,
     };
     static Rect reduce(const Rect& win, const Region& exclude);
     RequestedLayerState(const LayerCreationArgs&);
     void merge(const ResolvedComposerState&);
+    void clearChanges();
+
     // Currently we only care about the primary display
     ui::Transform getTransform(uint32_t displayRotationFlags) const;
     ui::Size getUnrotatedBufferSize(uint32_t displayRotationFlags) const;
@@ -72,6 +75,9 @@
     bool hasValidRelativeParent() const;
     bool hasInputInfo() const;
     bool hasBlur() const;
+    bool hasFrameUpdate() const;
+    bool hasReadyFrame() const;
+    bool hasSidebandStreamFrame() const;
 
     // Layer serial number.  This gives layers an explicit ordering, so we
     // have a stable sort order when their layer stack and Z-order are
@@ -110,6 +116,7 @@
     uint32_t touchCropId = UNASSIGNED_LAYER_ID;
     uint32_t bgColorLayerId = UNASSIGNED_LAYER_ID;
     ftl::Flags<RequestedLayerState::Changes> changes;
+    bool bgColorLayer = false;
 };
 
 } // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index dac0916..5ee701d 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2512,7 +2512,20 @@
 compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
         const DisplayDevice* display) const {
     if (!display) return nullptr;
-    return display->getCompositionDisplay()->getOutputLayerForLayer(getCompositionEngineLayerFE());
+    if (!mFlinger->mLayerLifecycleManagerEnabled) {
+        return display->getCompositionDisplay()->getOutputLayerForLayer(
+                getCompositionEngineLayerFE());
+    }
+    sp<LayerFE> layerFE;
+    frontend::LayerHierarchy::TraversalPath path{.id = static_cast<uint32_t>(sequence)};
+    for (auto& [p, layer] : mLayerFEs) {
+        if (p == path) {
+            layerFE = layer;
+        }
+    }
+
+    if (!layerFE) return nullptr;
+    return display->getCompositionDisplay()->getOutputLayerForLayer(layerFE);
 }
 
 Region Layer::getVisibleRegion(const DisplayDevice* display) const {
@@ -3275,11 +3288,11 @@
             (c.buffer != nullptr || c.bgColorLayer != nullptr);
 }
 
-void Layer::updateTexImage(nsecs_t latchTime) {
+void Layer::updateTexImage(nsecs_t latchTime, bool bgColorOnly) {
     const State& s(getDrawingState());
 
     if (!s.buffer) {
-        if (s.bgColorLayer) {
+        if (bgColorOnly) {
             for (auto& handle : mDrawingState.callbackHandles) {
                 handle->latchTime = latchTime;
             }
@@ -3476,7 +3489,7 @@
     }
 
     if (s.what & layer_state_t::eBackgroundColorChanged) {
-        if (mDrawingState.bgColorLayer || s.bgColorAlpha != 0) {
+        if (mDrawingState.bgColorLayer || s.bgColor.a != 0) {
             ALOGV("%s: false [eBackgroundColorChanged changed]", __func__);
             return false;
         }
@@ -3800,6 +3813,11 @@
 }
 
 bool Layer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) {
+    const bool bgColorOnly = mDrawingState.bgColorLayer != nullptr;
+    return latchBufferImpl(recomputeVisibleRegions, latchTime, bgColorOnly);
+}
+
+bool Layer::latchBufferImpl(bool& recomputeVisibleRegions, nsecs_t latchTime, bool bgColorOnly) {
     ATRACE_FORMAT_INSTANT("latchBuffer %s - %" PRIu64, getDebugName(),
                           getDrawingState().frameNumber);
 
@@ -3816,8 +3834,7 @@
         mFlinger->onLayerUpdate();
         return false;
     }
-
-    updateTexImage(latchTime);
+    updateTexImage(latchTime, bgColorOnly);
     if (mDrawingState.buffer == nullptr) {
         return false;
     }
@@ -4021,7 +4038,6 @@
     snapshot->bufferSize = getBufferSize(mDrawingState);
     snapshot->externalTexture = mBufferInfo.mBuffer;
     snapshot->hasReadyFrame = hasReadyFrame();
-    snapshot->isInternalDisplayOverlay = isInternalDisplayOverlay();
     preparePerFrameCompositionState();
 }
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 7d40774..9b7a405 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -427,6 +427,9 @@
      */
     bool latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/);
 
+    bool latchBufferImpl(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/,
+                         bool bgColorOnly);
+
     /*
      * Calls latchBuffer if the buffer has a frame queued and then releases the buffer.
      * This is used if the buffer is just latched and releases to free up the buffer
@@ -846,6 +849,7 @@
     void callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
                                    const sp<GraphicBuffer>& buffer, uint64_t framenumber,
                                    const sp<Fence>& releaseFence);
+    bool setFrameRateForLayerTree(FrameRate);
 
 protected:
     // For unit tests
@@ -1018,7 +1022,6 @@
 
     void updateTreeHasFrameRateVote();
     bool propagateFrameRateForLayerTree(FrameRate parentFrameRate, bool* transactionNeeded);
-    bool setFrameRateForLayerTree(FrameRate);
     void setZOrderRelativeOf(const wp<Layer>& relativeOf);
     bool isTrustedOverlay() const;
     gui::DropInputMode getDropInputMode() const;
@@ -1046,7 +1049,7 @@
 
     bool hasFrameUpdate() const;
 
-    void updateTexImage(nsecs_t latchTime);
+    void updateTexImage(nsecs_t latchTime, bool bgColorOnly = false);
 
     // Crop that applies to the buffer
     Rect computeBufferCrop(const State& s);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 5c8579c..29af6d1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2192,7 +2192,8 @@
                                       mLayerLifecycleManager.getDestroyedLayers());
     }
 
-    applyAndCommitDisplayTransactionStates(update.transactions);
+    bool mustComposite = false;
+    mustComposite |= applyAndCommitDisplayTransactionStates(update.transactions);
 
     {
         ATRACE_NAME("LayerSnapshotBuilder:update");
@@ -2216,23 +2217,37 @@
         mVisibleRegionsDirty = true;
     }
     outTransactionsAreEmpty = mLayerLifecycleManager.getGlobalChanges().get() == 0;
-    const bool mustComposite = mLayerLifecycleManager.getGlobalChanges().get() != 0;
-    {
-        ATRACE_NAME("LLM:commitChanges");
-        mLayerLifecycleManager.commitChanges();
-    }
+    mustComposite |= mLayerLifecycleManager.getGlobalChanges().get() != 0;
 
+    bool newDataLatched = false;
     if (!mLegacyFrontEndEnabled) {
         ATRACE_NAME("DisplayCallbackAndStatsUpdates");
         applyTransactions(update.transactions, vsyncId);
+        const nsecs_t latchTime = systemTime();
+        bool unused = false;
 
-        bool newDataLatched = false;
-        for (auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) {
-            if (!snapshot->changes.test(Changes::Buffer)) continue;
-            auto it = mLegacyLayers.find(snapshot->sequence);
+        for (auto& layer : mLayerLifecycleManager.getLayers()) {
+            if (layer->changes.test(frontend::RequestedLayerState::Changes::Created) &&
+                layer->bgColorLayer) {
+                sp<Layer> bgColorLayer = getFactory().createEffectLayer(
+                        LayerCreationArgs(this, nullptr, layer->name,
+                                          ISurfaceComposerClient::eFXSurfaceEffect, LayerMetadata(),
+                                          std::make_optional(layer->parentId), true));
+                mLegacyLayers[bgColorLayer->sequence] = bgColorLayer;
+            }
+            if (!layer->hasReadyFrame()) continue;
+
+            auto it = mLegacyLayers.find(layer->id);
             LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), "Couldnt find layer object for %s",
-                                snapshot->getDebugString().c_str());
+                                layer->getDebugString().c_str());
+            const bool bgColorOnly =
+                    !layer->externalTexture && (layer->bgColorLayerId != UNASSIGNED_LAYER_ID);
+            it->second->latchBufferImpl(unused, latchTime, bgColorOnly);
             mLayersWithQueuedFrames.emplace(it->second);
+        }
+
+        for (auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) {
+            if (!snapshot->hasReadyFrame) continue;
             newDataLatched = true;
             if (!snapshot->isVisible) break;
 
@@ -2245,6 +2260,11 @@
             mLegacyLayers.erase(destroyedLayer->id);
         }
 
+        {
+            ATRACE_NAME("LLM:commitChanges");
+            mLayerLifecycleManager.commitChanges();
+        }
+
         // enter boot animation on first buffer latch
         if (CC_UNLIKELY(mBootStage == BootStage::BOOTLOADER && newDataLatched)) {
             ALOGI("Enter boot animation");
@@ -2252,6 +2272,7 @@
         }
         commitTransactions();
     }
+    mustComposite |= (getTransactionFlags() & ~eTransactionFlushNeeded) || newDataLatched;
     return mustComposite;
 }
 
@@ -2885,14 +2906,19 @@
         }
 
         // We avoid any reverse traversal upwards so this shouldn't be too expensive
-        mDrawingState.traverse([&](Layer* layer) {
+        traverseLegacyLayers([&](Layer* layer) {
             if (!layer->hasTrustedPresentationListener()) {
                 return;
             }
-            const std::optional<const DisplayDevice*> displayOpt =
-                    layerStackToDisplay.get(layer->getLayerSnapshot()->outputFilter.layerStack);
+            const frontend::LayerSnapshot* snapshot = (mLayerLifecycleManagerEnabled)
+                    ? mLayerSnapshotBuilder.getSnapshot(layer->sequence)
+                    : layer->getLayerSnapshot();
+            std::optional<const DisplayDevice*> displayOpt = std::nullopt;
+            if (snapshot) {
+                displayOpt = layerStackToDisplay.get(snapshot->outputFilter.layerStack);
+            }
             const DisplayDevice* display = displayOpt.value_or(nullptr);
-            layer->updateTrustedPresentationState(display, layer->getLayerSnapshot(),
+            layer->updateTrustedPresentationState(display, snapshot,
                                                   nanoseconds_to_milliseconds(callTime), false);
         });
     }
@@ -4464,6 +4490,7 @@
         for (const auto& [_, display] : mDisplays) {
             mFrontEndDisplayInfos.try_emplace(display->getLayerStack(), display->getFrontEndInfo());
         }
+        needsTraversal = true;
     }
 
     return needsTraversal;
@@ -4643,7 +4670,7 @@
         }
     }
     if (what & layer_state_t::eBackgroundColorChanged) {
-        if (layer->setBackgroundColor(s.color.rgb, s.bgColorAlpha, s.bgColorDataspace)) {
+        if (layer->setBackgroundColor(s.bgColor.rgb, s.bgColor.a, s.bgColorDataspace)) {
             flags |= eTraversalNeeded;
         }
     }
@@ -4886,8 +4913,6 @@
                                                       uint64_t transactionId) {
     layer_state_t& s = composerState.state;
     s.sanitize(permissions);
-    const nsecs_t latchTime = systemTime();
-    bool unused;
 
     std::vector<ListenerCallbacks> filteredListeners;
     for (auto& listener : s.listeners) {
@@ -4940,6 +4965,12 @@
                     sp<CallbackHandle>::make(listener, callbackIds, s.surface));
         }
     }
+    // TODO(b/238781169) remove after screenshot refactor, currently screenshots
+    // requires to read drawing state from binder thread. So we need to fix that
+    // before removing this.
+    if (what & layer_state_t::eCropChanged) {
+        if (layer->setCrop(s.crop)) flags |= eTraversalNeeded;
+    }
     if (what & layer_state_t::eSidebandStreamChanged) {
         if (layer->setSidebandStream(s.sidebandStream)) flags |= eTraversalNeeded;
     }
@@ -4947,7 +4978,6 @@
         if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime,
                              desiredPresentTime, isAutoTimestamp, dequeueBufferTimestamp,
                              frameTimelineInfo)) {
-            layer->latchBuffer(unused, latchTime);
             flags |= eTraversalNeeded;
         }
         mLayersWithQueuedFrames.emplace(layer);
@@ -4960,11 +4990,22 @@
                                           s.trustedPresentationListener);
     }
 
-    const auto& snapshot = mLayerSnapshotBuilder.getSnapshot(layer->getSequence());
+    const auto& requestedLayerState = mLayerLifecycleManager.getLayerFromId(layer->getSequence());
     bool willPresentCurrentTransaction =
-            snapshot && (snapshot->hasReadyFrame || snapshot->sidebandStreamHasFrame);
+            requestedLayerState && requestedLayerState->hasReadyFrame();
     if (layer->setTransactionCompletedListeners(callbackHandles, willPresentCurrentTransaction))
         flags |= eTraversalNeeded;
+
+    for (auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) {
+        if (snapshot->path.isClone() ||
+            !snapshot->changes.test(frontend::RequestedLayerState::Changes::FrameRate))
+            continue;
+        auto it = mLegacyLayers.find(snapshot->sequence);
+        LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), "Couldnt find layer object for %s",
+                            snapshot->getDebugString().c_str());
+        it->second->setFrameRateForLayerTree(snapshot->frameRate);
+    }
+
     return flags;
 }
 
@@ -6922,7 +6963,7 @@
                                     ->schedule([=]() {
                                         bool protectedLayerFound = false;
                                         auto layers = getLayerSnapshots();
-                                        for (auto& [layer, layerFe] : layers) {
+                                        for (auto& [_, layerFe] : layers) {
                                             protectedLayerFound |=
                                                     (layerFe->mSnapshot->isVisible &&
                                                      layerFe->mSnapshot->hasProtectedContent);
@@ -7017,7 +7058,7 @@
     ATRACE_CALL();
 
     auto layers = getLayerSnapshots();
-    for (auto& [layer, layerFE] : layers) {
+    for (auto& [_, layerFE] : layers) {
         frontend::LayerSnapshot* snapshot = layerFE->mSnapshot.get();
         captureResults.capturedSecureLayers |= (snapshot->isVisible && snapshot->isSecure);
         captureResults.capturedHdrLayers |= isHdrLayer(*snapshot);
@@ -7133,6 +7174,16 @@
     return presentFuture;
 }
 
+void SurfaceFlinger::traverseLegacyLayers(const LayerVector::Visitor& visitor) const {
+    if (mLayerLifecycleManagerEnabled) {
+        for (auto& layer : mLegacyLayers) {
+            visitor(layer.second.get());
+        }
+    } else {
+        mDrawingState.traverse(visitor);
+    }
+}
+
 // ---------------------------------------------------------------------------
 
 void SurfaceFlinger::State::traverse(const LayerVector::Visitor& visitor) const {
@@ -7772,27 +7823,29 @@
 std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
 SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack,
                                                 uint32_t uid) {
-    return [this, layerStack, uid]() {
+    return [&, layerStack, uid]() {
         std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
-        for (auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) {
-            if (layerStack && snapshot->outputFilter.layerStack != *layerStack) {
-                continue;
-            }
-            if (uid != CaptureArgs::UNSET_UID && snapshot->inputInfo.ownerUid != uid) {
-                continue;
-            }
-            if (!snapshot->isVisible || !snapshot->hasSomethingToDraw()) {
-                continue;
-            }
+        mLayerSnapshotBuilder.forEachVisibleSnapshot(
+                [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) {
+                    if (layerStack && snapshot->outputFilter.layerStack != *layerStack) {
+                        return;
+                    }
+                    if (uid != CaptureArgs::UNSET_UID && snapshot->inputInfo.ownerUid != uid) {
+                        return;
+                    }
+                    if (!snapshot->hasSomethingToDraw()) {
+                        return;
+                    }
 
-            auto it = mLegacyLayers.find(snapshot->sequence);
-            LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), "Couldnt find layer object for %s",
-                                snapshot->getDebugString().c_str());
-            auto& legacyLayer = it->second;
-            sp<LayerFE> layerFE = getFactory().createLayerFE(legacyLayer->getName());
-            layerFE->mSnapshot = std::make_unique<frontend::LayerSnapshot>(*snapshot);
-            layers.emplace_back(legacyLayer.get(), std::move(layerFE));
-        }
+                    auto it = mLegacyLayers.find(snapshot->sequence);
+                    LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(),
+                                        "Couldnt find layer object for %s",
+                                        snapshot->getDebugString().c_str());
+                    Layer* legacyLayer = (it == mLegacyLayers.end()) ? nullptr : it->second.get();
+                    sp<LayerFE> layerFE = getFactory().createLayerFE(snapshot->name);
+                    layerFE->mSnapshot = std::make_unique<frontend::LayerSnapshot>(*snapshot);
+                    layers.emplace_back(legacyLayer, std::move(layerFE));
+                });
 
         return layers;
     };
@@ -7802,11 +7855,13 @@
 SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t uid,
                                                 std::unordered_set<uint32_t> excludeLayerIds,
                                                 bool childrenOnly, const FloatRect& parentCrop) {
-    return [this, excludeLayerIds = std::move(excludeLayerIds), uid, rootLayerId, childrenOnly,
+    return [&, rootLayerId, uid, excludeLayerIds = std::move(excludeLayerIds), childrenOnly,
             parentCrop]() {
+        auto root = mLayerHierarchyBuilder.getPartialHierarchy(rootLayerId, childrenOnly);
         frontend::LayerSnapshotBuilder::Args
-                args{.root = mLayerHierarchyBuilder.getPartialHierarchy(rootLayerId, childrenOnly),
+                args{.root = root,
                      .layerLifecycleManager = mLayerLifecycleManager,
+                     .forceUpdate = frontend::LayerSnapshotBuilder::ForceUpdateFlags::HIERARCHY,
                      .displays = mFrontEndDisplayInfos,
                      .displayChanges = true,
                      .globalShadowSettings = mDrawingState.globalShadowSettings,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b41f414..adba9b8 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1126,6 +1126,7 @@
 
     ui::Rotation getPhysicalDisplayOrientation(DisplayId, bool isPrimary) const
             REQUIRES(mStateLock);
+    void traverseLegacyLayers(const LayerVector::Visitor& visitor) const;
 
     sp<StartPropertySetThread> mStartPropertySetThread;
     surfaceflinger::Factory& mFactory;
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
index 2f46487..e0ef8a5 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
@@ -220,12 +220,12 @@
         }
     }
     if (layer.what & layer_state_t::eBackgroundColorChanged) {
-        proto.set_bg_color_alpha(layer.bgColorAlpha);
+        proto.set_bg_color_alpha(layer.bgColor.a);
         proto.set_bg_color_dataspace(static_cast<int32_t>(layer.bgColorDataspace));
         proto::LayerState_Color3* colorProto = proto.mutable_color();
-        colorProto->set_r(layer.color.r);
-        colorProto->set_g(layer.color.g);
-        colorProto->set_b(layer.color.b);
+        colorProto->set_r(layer.bgColor.r);
+        colorProto->set_g(layer.bgColor.g);
+        colorProto->set_b(layer.bgColor.b);
     }
     if (layer.what & layer_state_t::eColorSpaceAgnosticChanged) {
         proto.set_color_space_agnostic(layer.colorSpaceAgnostic);
@@ -501,12 +501,12 @@
         layer.windowInfoHandle = sp<gui::WindowInfoHandle>::make(inputInfo);
     }
     if (proto.what() & layer_state_t::eBackgroundColorChanged) {
-        layer.bgColorAlpha = proto.bg_color_alpha();
+        layer.bgColor.a = proto.bg_color_alpha();
         layer.bgColorDataspace = static_cast<ui::Dataspace>(proto.bg_color_dataspace());
         const proto::LayerState_Color3& colorProto = proto.color();
-        layer.color.r = colorProto.r();
-        layer.color.g = colorProto.g();
-        layer.color.b = colorProto.b();
+        layer.bgColor.r = colorProto.r();
+        layer.bgColor.g = colorProto.g();
+        layer.bgColor.b = colorProto.b();
     }
     if (proto.what() & layer_state_t::eColorSpaceAgnosticChanged) {
         layer.colorSpaceAgnostic = proto.color_space_agnostic();
diff --git a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
index bf7cae9..0b8c51e 100644
--- a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
@@ -544,6 +544,7 @@
             .apply();
 
     {
+        SCOPED_TRACE("final color");
         auto shot = screenshot();
         shot->expectColor(Rect(0, 0, width, height), finalColor);
         shot->expectBorder(Rect(0, 0, width, height), Color::BLACK);
diff --git a/services/surfaceflinger/tests/MirrorLayer_test.cpp b/services/surfaceflinger/tests/MirrorLayer_test.cpp
index e69db7c..0ea0824 100644
--- a/services/surfaceflinger/tests/MirrorLayer_test.cpp
+++ b/services/surfaceflinger/tests/MirrorLayer_test.cpp
@@ -18,6 +18,7 @@
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wconversion"
 
+#include <android-base/properties.h>
 #include <private/android_filesystem_config.h>
 #include "LayerTransactionTest.h"
 #include "utils/TransactionUtils.h"
@@ -119,15 +120,20 @@
         shot->expectColor(Rect(750, 750, 950, 950), Color::BLACK);
     }
 
-    // Remove child layer
+    if (base::GetBoolProperty("debug.sf.enable_legacy_frontend", true)) {
+        GTEST_SKIP() << "Skipping test because mirroring behavior changes with legacy frontend";
+    }
+
+    // Remove child layer and verify we can still mirror the layer when
+    // its offscreen.
     Transaction().reparent(mChildLayer, nullptr).apply();
     {
         SCOPED_TRACE("Removed Child Layer");
         auto shot = screenshot();
         // Grandchild mirror
-        shot->expectColor(Rect(550, 550, 750, 750), Color::RED);
+        shot->expectColor(Rect(550, 550, 750, 750), Color::BLACK);
         // Child mirror
-        shot->expectColor(Rect(750, 750, 950, 950), Color::RED);
+        shot->expectColor(Rect(750, 750, 950, 950), Color::BLACK);
     }
 
     // Add grandchild layer to offscreen layer
@@ -136,9 +142,9 @@
         SCOPED_TRACE("Added Grandchild Layer");
         auto shot = screenshot();
         // Grandchild mirror
-        shot->expectColor(Rect(550, 550, 750, 750), Color::RED);
+        shot->expectColor(Rect(550, 550, 750, 750), Color::WHITE);
         // Child mirror
-        shot->expectColor(Rect(750, 750, 950, 950), Color::RED);
+        shot->expectColor(Rect(750, 750, 950, 950), Color::BLACK);
     }
 
     // Add child layer
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp
index 763426a..1916404 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp
@@ -437,10 +437,11 @@
 
     updateBackgroundColor(1, 0.5);
     UPDATE_AND_VERIFY(hierarchyBuilder);
-
-    std::vector<uint32_t> expectedTraversalPath = {1, 1222, 11, 111, 12, 121, 122, 1221, 13, 2};
+    auto bgLayerId = LayerCreationArgs::getInternalLayerId(1);
+    std::vector<uint32_t> expectedTraversalPath = {1,   bgLayerId, 11,   111, 12,
+                                                   121, 122,       1221, 13,  2};
     EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
-    expectedTraversalPath = {1222, 1, 11, 111, 12, 121, 122, 1221, 13, 2};
+    expectedTraversalPath = {bgLayerId, 1, 11, 111, 12, 121, 122, 1221, 13, 2};
     EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
     expectedTraversalPath = {};
     EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index 852cb91..cdcc6f4 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -172,7 +172,7 @@
         transactions.emplace_back();
         transactions.back().states.push_back({});
         transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged;
-        transactions.back().states.front().state.bgColorAlpha = alpha;
+        transactions.back().states.front().state.bgColor.a = alpha;
         transactions.back().states.front().state.surface = mHandles[id];
         mLifecycleManager.applyTransactions(transactions);
     }
diff --git a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
index 89440a6..99c1d23 100644
--- a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
@@ -372,7 +372,7 @@
     std::vector<TransactionState> transactions;
     transactions.emplace_back();
     transactions.back().states.push_back({});
-    transactions.back().states.front().state.bgColorAlpha = 0.5;
+    transactions.back().states.front().state.bgColor.a = 0.5;
     transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged;
     sp<LayerHandle> handle = sp<LayerHandle>::make(1u);
     transactions.back().states.front().state.surface = handle;
@@ -383,9 +383,10 @@
 
     EXPECT_TRUE(lifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy));
     lifecycleManager.commitChanges();
-    listener->expectLayersAdded({1, 2});
+    auto bgLayerId = LayerCreationArgs::getInternalLayerId(1);
+    listener->expectLayersAdded({1, bgLayerId});
     listener->expectLayersDestroyed({});
-    EXPECT_EQ(getRequestedLayerState(lifecycleManager, 2)->color.a, 0.5_hf);
+    EXPECT_EQ(getRequestedLayerState(lifecycleManager, bgLayerId)->color.a, 0.5_hf);
 }
 
 TEST_F(LayerLifecycleManagerTest, canDestroyBackgroundLayer) {
@@ -400,13 +401,13 @@
     std::vector<TransactionState> transactions;
     transactions.emplace_back();
     transactions.back().states.push_back({});
-    transactions.back().states.front().state.bgColorAlpha = 0.5;
+    transactions.back().states.front().state.bgColor.a = 0.5;
     transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged;
     sp<LayerHandle> handle = sp<LayerHandle>::make(1u);
     transactions.back().states.front().state.surface = handle;
     transactions.emplace_back();
     transactions.back().states.push_back({});
-    transactions.back().states.front().state.bgColorAlpha = 0;
+    transactions.back().states.front().state.bgColor.a = 0;
     transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged;
     transactions.back().states.front().state.surface = handle;
 
@@ -417,8 +418,9 @@
 
     EXPECT_TRUE(lifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy));
     lifecycleManager.commitChanges();
-    listener->expectLayersAdded({1, 2});
-    listener->expectLayersDestroyed({2});
+    auto bgLayerId = LayerCreationArgs::getInternalLayerId(1);
+    listener->expectLayersAdded({1, bgLayerId});
+    listener->expectLayersDestroyed({bgLayerId});
 }
 
 TEST_F(LayerLifecycleManagerTest, onParentDestroyDestroysBackgroundLayer) {
@@ -433,7 +435,7 @@
     std::vector<TransactionState> transactions;
     transactions.emplace_back();
     transactions.back().states.push_back({});
-    transactions.back().states.front().state.bgColorAlpha = 0.5;
+    transactions.back().states.front().state.bgColor.a = 0.5;
     transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged;
     sp<LayerHandle> handle = sp<LayerHandle>::make(1u);
     transactions.back().states.front().state.surface = handle;
@@ -446,8 +448,9 @@
 
     EXPECT_TRUE(lifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy));
     lifecycleManager.commitChanges();
-    listener->expectLayersAdded({1, 2});
-    listener->expectLayersDestroyed({1, 2});
+    auto bgLayerId = LayerCreationArgs::getInternalLayerId(1);
+    listener->expectLayersAdded({1, bgLayerId});
+    listener->expectLayersDestroyed({1, bgLayerId});
 }
 
 } // namespace android::surfaceflinger::frontend