SF: Introduce new frontend logic

Changes to allow creating layer snapshots using the new
and legacy frontend logic. Switching the logic is controlled
by debug flags. By default SF will continue to use the
legacy logic so there should be no functional changes with
this cl.

Bug: 238781169
Test: presubmit

Change-Id: I33a4de1b8e93fbfe02ac1787d57d6e07a8c3ef26
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index 6490476..3ed24b2 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -391,7 +391,9 @@
 
 void LayerSnapshotBuilder::updateSnapshots(const Args& args) {
     ATRACE_NAME("UpdateSnapshots");
-    if (args.forceUpdate || args.displayChanges) {
+    if (args.parentCrop) {
+        mRootSnapshot.geomLayerBounds = *args.parentCrop;
+    } else if (args.forceUpdate || args.displayChanges) {
         mRootSnapshot.geomLayerBounds = getMaxDisplayBounds(args.displays);
     }
     if (args.displayChanges) {
@@ -618,7 +620,8 @@
              RequestedLayerState::Changes::AffectsChildren);
     snapshot.changes = parentChanges | requested.changes;
     snapshot.isHiddenByPolicyFromParent = parentSnapshot.isHiddenByPolicyFromParent ||
-            parentSnapshot.invalidTransform || requested.isHiddenByPolicy();
+            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 =
@@ -983,6 +986,20 @@
     }
 }
 
+// Visit each visible snapshot in z-order
+void LayerSnapshotBuilder::forEachVisibleSnapshot(const ConstVisitor& visitor,
+                                                  const LayerHierarchy& root) const {
+    root.traverseInZOrder(
+            [this, visitor](const LayerHierarchy&,
+                            const LayerHierarchy::TraversalPath& traversalPath) -> bool {
+                LayerSnapshot* snapshot = getSnapshot(traversalPath);
+                if (snapshot && snapshot->isVisible) {
+                    visitor(*snapshot);
+                }
+                return true;
+            });
+}
+
 void LayerSnapshotBuilder::forEachVisibleSnapshot(const Visitor& visitor) {
     for (int i = 0; i < mNumInterestingSnapshots; i++) {
         std::unique_ptr<LayerSnapshot>& snapshot = mSnapshots.at((size_t)i);
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
index abb7e66..f4544fd 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
@@ -36,7 +36,7 @@
 class LayerSnapshotBuilder {
 public:
     struct Args {
-        const LayerHierarchy& root;
+        LayerHierarchy root;
         const LayerLifecycleManager& layerLifecycleManager;
         bool forceUpdate = false;
         bool includeMetadata = false;
@@ -46,6 +46,8 @@
         const renderengine::ShadowSettings& globalShadowSettings;
         bool supportsBlur = true;
         bool forceFullDamage = false;
+        std::optional<FloatRect> parentCrop = std::nullopt;
+        std::unordered_set<uint32_t> excludeLayerIds;
     };
     LayerSnapshotBuilder();
 
@@ -65,6 +67,9 @@
     // Visit each visible snapshot in z-order
     void forEachVisibleSnapshot(const ConstVisitor& visitor) const;
 
+    // Visit each visible snapshot in z-order
+    void forEachVisibleSnapshot(const ConstVisitor& visitor, const LayerHierarchy& root) const;
+
     typedef std::function<void(std::unique_ptr<LayerSnapshot>& snapshot)> Visitor;
     // Visit each visible snapshot in z-order and move the snapshot if needed
     void forEachVisibleSnapshot(const Visitor& visitor);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index b6b9965..31ee91e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -146,7 +146,7 @@
         mLayerCreationFlags(args.flags),
         mBorderEnabled(false),
         mTextureName(args.textureName),
-        mLayerFE(args.flinger->getFactory().createLayerFE(mName)) {
+        mLegacyLayerFE(args.flinger->getFactory().createLayerFE(mName)) {
     ALOGV("Creating Layer %s", getDebugName());
 
     uint32_t layerFlags = 0;
@@ -3098,15 +3098,14 @@
     return true;
 }
 
-bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) {
+bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles,
+                                             bool willPresent) {
     // If there is no handle, we will not send a callback so reset mReleasePreviousBuffer and return
     if (handles.empty()) {
         mReleasePreviousBuffer = false;
         return false;
     }
 
-    const bool willPresent = willPresentCurrentTransaction();
-
     for (const auto& handle : handles) {
         // If this transaction set a buffer on this layer, release its previous buffer
         handle->releasePreviousBuffer = mReleasePreviousBuffer;
@@ -3180,11 +3179,10 @@
     return fenceSignaled;
 }
 
-bool Layer::onPreComposition(nsecs_t refreshStartTime) {
+void Layer::onPreComposition(nsecs_t refreshStartTime) {
     for (const auto& handle : mDrawingState.callbackHandles) {
         handle->refreshStartTime = refreshStartTime;
     }
-    return hasReadyFrame();
 }
 
 void Layer::setAutoRefresh(bool autoRefresh) {
@@ -3570,7 +3568,7 @@
 
 sp<LayerFE> Layer::getCompositionEngineLayerFE() const {
     // There's no need to get a CE Layer if the layer isn't going to draw anything.
-    return hasSomethingToDraw() ? mLayerFE : nullptr;
+    return hasSomethingToDraw() ? mLegacyLayerFE : nullptr;
 }
 
 const LayerSnapshot* Layer::getLayerSnapshot() const {
@@ -3581,16 +3579,36 @@
     return mSnapshot.get();
 }
 
+std::unique_ptr<frontend::LayerSnapshot> Layer::stealLayerSnapshot() {
+    return std::move(mSnapshot);
+}
+
+void Layer::updateLayerSnapshot(std::unique_ptr<frontend::LayerSnapshot> snapshot) {
+    mSnapshot = std::move(snapshot);
+}
+
 const compositionengine::LayerFECompositionState* Layer::getCompositionState() const {
     return mSnapshot.get();
 }
 
 sp<LayerFE> Layer::copyCompositionEngineLayerFE() const {
-    auto result = mFlinger->getFactory().createLayerFE(mLayerFE->getDebugName());
+    auto result = mFlinger->getFactory().createLayerFE(mName);
     result->mSnapshot = std::make_unique<LayerSnapshot>(*mSnapshot);
     return result;
 }
 
+sp<LayerFE> Layer::getCompositionEngineLayerFE(
+        const frontend::LayerHierarchy::TraversalPath& path) {
+    for (auto& [p, layerFE] : mLayerFEs) {
+        if (p == path) {
+            return layerFE;
+        }
+    }
+    auto layerFE = mFlinger->getFactory().createLayerFE(mName);
+    mLayerFEs.emplace_back(path, layerFE);
+    return layerFE;
+}
+
 void Layer::useSurfaceDamage() {
     if (mFlinger->mForceFullDamage) {
         surfaceDamageRegion = Region::INVALID_REGION;
@@ -3986,28 +4004,6 @@
     }
 }
 
-LayerSnapshotGuard::LayerSnapshotGuard(Layer* layer) : mLayer(layer) {
-    if (mLayer) {
-        mLayer->mLayerFE->mSnapshot = std::move(mLayer->mSnapshot);
-    }
-}
-
-LayerSnapshotGuard::~LayerSnapshotGuard() {
-    if (mLayer) {
-        mLayer->mSnapshot = std::move(mLayer->mLayerFE->mSnapshot);
-    }
-}
-
-LayerSnapshotGuard::LayerSnapshotGuard(LayerSnapshotGuard&& other) : mLayer(other.mLayer) {
-    other.mLayer = nullptr;
-}
-
-LayerSnapshotGuard& LayerSnapshotGuard::operator=(LayerSnapshotGuard&& other) {
-    mLayer = other.mLayer;
-    other.mLayer = nullptr;
-    return *this;
-}
-
 void Layer::setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds,
                                        TrustedPresentationListener const& listener) {
     bool hadTrustedPresentationListener = hasTrustedPresentationListener();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f858224..3d4f03f 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -307,7 +307,8 @@
     bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/);
     bool setApi(int32_t /*api*/);
     bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/);
-    bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& /*handles*/);
+    bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& /*handles*/,
+                                          bool willPresent);
     virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace);
     virtual bool setColorSpaceAgnostic(const bool agnostic);
     virtual bool setDimmingEnabled(const bool dimmingEnabled);
@@ -328,9 +329,12 @@
 
     virtual sp<LayerFE> getCompositionEngineLayerFE() const;
     virtual sp<LayerFE> copyCompositionEngineLayerFE() const;
+    sp<LayerFE> getCompositionEngineLayerFE(const frontend::LayerHierarchy::TraversalPath&);
 
     const frontend::LayerSnapshot* getLayerSnapshot() const;
     frontend::LayerSnapshot* editLayerSnapshot();
+    std::unique_ptr<frontend::LayerSnapshot> stealLayerSnapshot();
+    void updateLayerSnapshot(std::unique_ptr<frontend::LayerSnapshot> snapshot);
 
     // If we have received a new buffer this frame, we will pass its surface
     // damage down to hardware composer. Otherwise, we must send a region with
@@ -512,7 +516,7 @@
     // implements compositionengine::LayerFE
     const compositionengine::LayerFECompositionState* getCompositionState() const;
     bool fenceHasSignaled() const;
-    bool onPreComposition(nsecs_t refreshStartTime);
+    void onPreComposition(nsecs_t refreshStartTime);
     void onLayerDisplayed(ftl::SharedFuture<FenceResult>);
 
     void setWasClientComposed(const sp<Fence>& fence) {
@@ -832,6 +836,7 @@
     void updateMetadataSnapshot(const LayerMetadata& parentMetadata);
     void updateRelativeMetadataSnapshot(const LayerMetadata& relativeLayerMetadata,
                                         std::unordered_set<Layer*>& visited);
+    bool willPresentCurrentTransaction() const;
 
 protected:
     // For unit tests
@@ -1037,8 +1042,6 @@
     // Crop that applies to the buffer
     Rect computeBufferCrop(const State& s);
 
-    bool willPresentCurrentTransaction() const;
-
     void callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
                                    const sp<GraphicBuffer>& buffer, uint64_t framenumber,
                                    const sp<Fence>& releaseFence,
@@ -1146,34 +1149,10 @@
     // not specify a destination frame.
     ui::Transform mRequestedTransform;
 
-    sp<LayerFE> mLayerFE;
+    sp<LayerFE> mLegacyLayerFE;
+    std::vector<std::pair<frontend::LayerHierarchy::TraversalPath, sp<LayerFE>>> mLayerFEs;
     std::unique_ptr<frontend::LayerSnapshot> mSnapshot =
             std::make_unique<frontend::LayerSnapshot>();
-
-    friend class LayerSnapshotGuard;
-};
-
-// LayerSnapshotGuard manages the movement of LayerSnapshot between a Layer and its corresponding
-// LayerFE. This class must be used whenever LayerFEs are passed to CompositionEngine. Instances of
-// LayerSnapshotGuard should only be constructed on the main thread and should not be moved outside
-// the main thread.
-//
-// Moving the snapshot instead of sharing common state prevents use of LayerFE outside the main
-// thread by making errors obvious (i.e. use outside the main thread results in SEGFAULTs due to
-// nullptr dereference).
-class LayerSnapshotGuard {
-public:
-    LayerSnapshotGuard(Layer* layer) REQUIRES(kMainThreadContext);
-    ~LayerSnapshotGuard() REQUIRES(kMainThreadContext);
-
-    LayerSnapshotGuard(const LayerSnapshotGuard&) = delete;
-    LayerSnapshotGuard& operator=(const LayerSnapshotGuard&) = delete;
-
-    LayerSnapshotGuard(LayerSnapshotGuard&& other) REQUIRES(kMainThreadContext);
-    LayerSnapshotGuard& operator=(LayerSnapshotGuard&& other) REQUIRES(kMainThreadContext);
-
-private:
-    Layer* mLayer;
 };
 
 std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate);
diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp
index 2b4375b..03a7f22 100644
--- a/services/surfaceflinger/LayerRenderArea.cpp
+++ b/services/surfaceflinger/LayerRenderArea.cpp
@@ -69,6 +69,14 @@
 void LayerRenderArea::render(std::function<void()> drawLayers) {
     using namespace std::string_literals;
 
+    if (!mChildrenOnly) {
+        mTransform = mLayer->getTransform().inverse();
+    }
+
+    if (mFlinger.mLayerLifecycleManagerEnabled) {
+        drawLayers();
+        return;
+    }
     // If layer is offscreen, update mirroring info if it exists
     if (mLayer->isRemovedFromCurrentState()) {
         mLayer->traverse(LayerVector::StateSet::Drawing,
@@ -78,7 +86,6 @@
     }
 
     if (!mChildrenOnly) {
-        mTransform = mLayer->getTransform().inverse();
         // If the layer is offscreen, compute bounds since we don't compute bounds for offscreen
         // layers in a regular cycles.
         if (mLayer->isRemovedFromCurrentState()) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 6020aba..c10ef94 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -173,6 +173,8 @@
 using namespace hardware::configstore;
 using namespace hardware::configstore::V1_0;
 using namespace sysprop;
+using ftl::Flags;
+using namespace ftl::flag_operators;
 
 using aidl::android::hardware::graphics::common::DisplayDecorationSupport;
 using aidl::android::hardware::graphics::composer3::Capability;
@@ -470,6 +472,10 @@
     mPowerHintSessionMode =
             {.late = base::GetBoolProperty("debug.sf.send_late_power_session_hint"s, true),
              .early = base::GetBoolProperty("debug.sf.send_early_power_session_hint"s, false)};
+    mLayerLifecycleManagerEnabled =
+            base::GetBoolProperty("debug.sf.enable_layer_lifecycle_manager"s, false);
+    mLegacyFrontEndEnabled = !mLayerLifecycleManagerEnabled ||
+            base::GetBoolProperty("debug.sf.enable_legacy_frontend"s, true);
 }
 
 LatchUnsignaledConfig SurfaceFlinger::getLatchUnsignaledConfig() {
@@ -2136,6 +2142,110 @@
     }
 }
 
+bool SurfaceFlinger::updateLayerSnapshotsLegacy(VsyncId vsyncId, LifecycleUpdate& update,
+                                                bool transactionsFlushed,
+                                                bool& outTransactionsAreEmpty) {
+    bool needsTraversal = false;
+    if (transactionsFlushed) {
+        needsTraversal |= commitMirrorDisplays(vsyncId);
+        needsTraversal |= commitCreatedLayers(vsyncId, update.layerCreatedStates);
+        needsTraversal |= applyTransactions(update.transactions, vsyncId);
+    }
+    outTransactionsAreEmpty = !needsTraversal;
+    const bool shouldCommit = (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal;
+    if (shouldCommit) {
+        commitTransactions();
+    }
+
+    bool mustComposite = latchBuffers() || shouldCommit;
+    updateLayerGeometry();
+    return mustComposite;
+}
+
+bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, LifecycleUpdate& update,
+                                          bool transactionsFlushed, bool& outTransactionsAreEmpty) {
+    using Changes = frontend::RequestedLayerState::Changes;
+    ATRACE_NAME("updateLayerSnapshots");
+    {
+        mLayerLifecycleManager.addLayers(std::move(update.newLayers));
+        mLayerLifecycleManager.applyTransactions(update.transactions);
+        mLayerLifecycleManager.onHandlesDestroyed(update.destroyedHandles);
+        for (auto& legacyLayer : update.layerCreatedStates) {
+            sp<Layer> layer = legacyLayer.layer.promote();
+            if (layer) {
+                mLegacyLayers[layer->sequence] = layer;
+            }
+        }
+    }
+    if (mLayerLifecycleManager.getGlobalChanges().test(Changes::Hierarchy)) {
+        ATRACE_NAME("LayerHierarchyBuilder:update");
+        mLayerHierarchyBuilder.update(mLayerLifecycleManager.getLayers(),
+                                      mLayerLifecycleManager.getDestroyedLayers());
+    }
+
+    applyAndCommitDisplayTransactionStates(update.transactions);
+
+    {
+        ATRACE_NAME("LayerSnapshotBuilder:update");
+        frontend::LayerSnapshotBuilder::Args args{.root = mLayerHierarchyBuilder.getHierarchy(),
+                                                  .layerLifecycleManager = mLayerLifecycleManager,
+                                                  .displays = mFrontEndDisplayInfos,
+                                                  .displayChanges = mFrontEndDisplayInfosChanged,
+                                                  .globalShadowSettings =
+                                                          mDrawingState.globalShadowSettings,
+                                                  .supportsBlur = mSupportsBlur,
+                                                  .forceFullDamage = mForceFullDamage};
+        mLayerSnapshotBuilder.update(args);
+    }
+
+    if (mLayerLifecycleManager.getGlobalChanges().any(Changes::Geometry | Changes::Input |
+                                                      Changes::Hierarchy)) {
+        mUpdateInputInfo = true;
+    }
+    if (mLayerLifecycleManager.getGlobalChanges().any(Changes::VisibleRegion | Changes::Hierarchy |
+                                                      Changes::Visibility)) {
+        mVisibleRegionsDirty = true;
+    }
+    outTransactionsAreEmpty = mLayerLifecycleManager.getGlobalChanges().get() == 0;
+    const bool mustComposite = mLayerLifecycleManager.getGlobalChanges().get() != 0;
+    {
+        ATRACE_NAME("LLM:commitChanges");
+        mLayerLifecycleManager.commitChanges();
+    }
+
+    if (!mLegacyFrontEndEnabled) {
+        ATRACE_NAME("DisplayCallbackAndStatsUpdates");
+        applyTransactions(update.transactions, vsyncId);
+
+        bool newDataLatched = false;
+        for (auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) {
+            if (!snapshot->changes.test(Changes::Buffer)) continue;
+            auto it = mLegacyLayers.find(snapshot->sequence);
+            LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), "Couldnt find layer object for %s",
+                                snapshot->getDebugString().c_str());
+            mLayersWithQueuedFrames.emplace(it->second);
+            newDataLatched = true;
+            if (!snapshot->isVisible) break;
+
+            Region visibleReg;
+            visibleReg.set(snapshot->transformedBoundsWithoutTransparentRegion);
+            invalidateLayerStack(snapshot->outputFilter, visibleReg);
+        }
+
+        for (auto& destroyedLayer : mLayerLifecycleManager.getDestroyedLayers()) {
+            mLegacyLayers.erase(destroyedLayer->id);
+        }
+
+        // enter boot animation on first buffer latch
+        if (CC_UNLIKELY(mBootStage == BootStage::BOOTLOADER && newDataLatched)) {
+            ALOGI("Enter boot animation");
+            mBootStage = BootStage::BOOTANIMATION;
+        }
+        commitTransactions();
+    }
+    return mustComposite;
+}
+
 bool SurfaceFlinger::commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expectedVsyncTime)
         FTL_FAKE_GUARD(kMainThreadContext) {
     // The expectedVsyncTime, which was predicted when this frame was scheduled, is normally in the
@@ -2275,45 +2385,34 @@
         mFrameTimeline->setSfWakeUp(vsyncId.value, frameTime.ns(),
                                     Fps::fromPeriodNsecs(vsyncPeriod.ns()));
 
-        bool needsTraversal = false;
-        if (clearTransactionFlags(eTransactionFlushNeeded)) {
-            // Locking:
-            // 1. to prevent onHandleDestroyed from being called while the state lock is held,
-            // we must keep a copy of the transactions (specifically the composer
-            // states) around outside the scope of the lock.
-            // 2. Transactions and created layers do not share a lock. To prevent applying
-            // transactions with layers still in the createdLayer queue, flush the transactions
-            // before committing the created layers.
-            std::vector<TransactionState> transactions = mTransactionHandler.flushTransactions();
-            needsTraversal |= commitMirrorDisplays(vsyncId);
-            needsTraversal |= commitCreatedLayers(vsyncId);
-            needsTraversal |= applyTransactions(transactions, vsyncId);
+        const bool flushTransactions = clearTransactionFlags(eTransactionFlushNeeded);
+        LifecycleUpdate updates;
+        if (flushTransactions) {
+            updates = flushLifecycleUpdates();
         }
-
-        const bool shouldCommit =
-                (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal;
-        if (shouldCommit) {
-            commitTransactions();
+        bool transactionsAreEmpty;
+        if (mLegacyFrontEndEnabled) {
+            mustComposite |= updateLayerSnapshotsLegacy(vsyncId, updates, flushTransactions,
+                                                        transactionsAreEmpty);
+        }
+        if (mLayerLifecycleManagerEnabled) {
+            mustComposite |=
+                    updateLayerSnapshots(vsyncId, updates, flushTransactions, transactionsAreEmpty);
         }
 
         if (transactionFlushNeeded()) {
             setTransactionFlags(eTransactionFlushNeeded);
         }
 
-        mustComposite |= shouldCommit;
-        mustComposite |= latchBuffers();
-
         // This has to be called after latchBuffers because we want to include the layers that have
         // been latched in the commit callback
-        if (!needsTraversal) {
+        if (transactionsAreEmpty) {
             // Invoke empty transaction callbacks early.
             mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
         } else {
             // Invoke OnCommit callbacks.
             mTransactionCallbackInvoker.sendCallbacks(true /* onCommitOnly */);
         }
-
-        updateLayerGeometry();
     }
 
     // Layers need to get updated (in the previous line) before we can use them for
@@ -2400,15 +2499,6 @@
 
     refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;
     refreshArgs.updatingGeometryThisFrame = mGeometryDirty.exchange(false) || mVisibleRegionsDirty;
-    std::vector<Layer*> layers;
-
-    mDrawingState.traverseInZOrder([&refreshArgs, &layers](Layer* layer) {
-        if (auto layerFE = layer->getCompositionEngineLayerFE()) {
-            layer->updateSnapshot(refreshArgs.updatingGeometryThisFrame);
-            refreshArgs.layers.push_back(layerFE);
-            layers.push_back(layer);
-        }
-    });
     refreshArgs.internalDisplayRotationFlags = DisplayDevice::getPrimaryDisplayRotationFlags();
 
     if (CC_UNLIKELY(mDrawingState.colorMatrixChanged)) {
@@ -2435,17 +2525,13 @@
     // the scheduler.
     const auto presentTime = systemTime();
 
-    {
-        std::vector<LayerSnapshotGuard> layerSnapshotGuards;
-        for (Layer* layer : layers) {
-            layerSnapshotGuards.emplace_back(layer);
-        }
-        mCompositionEngine->present(refreshArgs);
-    }
+    std::vector<std::pair<Layer*, LayerFE*>> layers =
+            moveSnapshotsToCompositionArgs(refreshArgs, /*cursorOnly=*/false, vsyncId.value);
+    mCompositionEngine->present(refreshArgs);
+    moveSnapshotsFromCompositionArgs(refreshArgs, layers);
 
-    for (auto& layer : layers) {
-        CompositionResult compositionResult{
-                layer->getCompositionEngineLayerFE()->stealCompositionResult()};
+    for (auto [layer, layerFE] : layers) {
+        CompositionResult compositionResult{layerFE->stealCompositionResult()};
         layer->onPreComposition(compositionResult.refreshStartTime);
         for (auto releaseFence : compositionResult.releaseFences) {
             layer->onLayerDisplayed(releaseFence);
@@ -2539,7 +2625,7 @@
     for (auto& layer : mLayersPendingRefresh) {
         Region visibleReg;
         visibleReg.set(layer->getScreenBounds());
-        invalidateLayerStack(layer, visibleReg);
+        invalidateLayerStack(layer->getOutputFilter(), visibleReg);
     }
     mLayersPendingRefresh.clear();
 }
@@ -3397,7 +3483,8 @@
 void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) {
     // Commit display transactions.
     const bool displayTransactionNeeded = transactionFlags & eDisplayTransactionNeeded;
-    if (displayTransactionNeeded) {
+    mFrontEndDisplayInfosChanged = displayTransactionNeeded;
+    if (displayTransactionNeeded && !mLayerLifecycleManagerEnabled) {
         processDisplayChangesLocked();
         mFrontEndDisplayInfos.clear();
         for (const auto& [_, display] : mDisplays) {
@@ -3488,7 +3575,7 @@
                 // this layer is not visible anymore
                 Region visibleReg;
                 visibleReg.set(layer->getScreenBounds());
-                invalidateLayerStack(sp<Layer>::fromExisting(layer), visibleReg);
+                invalidateLayerStack(layer->getOutputFilter(), visibleReg);
             }
         });
     }
@@ -3576,16 +3663,23 @@
     outWindowInfos.reserve(sNumWindowInfos);
     sNumWindowInfos = 0;
 
-    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
-        if (!layer->needsInputInfo()) return;
+    if (mLayerLifecycleManagerEnabled) {
+        mLayerSnapshotBuilder.forEachInputSnapshot(
+                [&outWindowInfos](const frontend::LayerSnapshot& snapshot) {
+                    outWindowInfos.push_back(snapshot.inputInfo);
+                });
+    } else {
+        mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
+            if (!layer->needsInputInfo()) return;
+            const auto opt =
+                    mFrontEndDisplayInfos.get(layer->getLayerStack())
+                            .transform([](const frontend::DisplayInfo& info) {
+                                return Layer::InputDisplayArgs{&info.transform, info.isSecure};
+                            });
 
-        const auto opt = mFrontEndDisplayInfos.get(layer->getLayerStack())
-                                 .transform([](const frontend::DisplayInfo& info) {
-                                     return Layer::InputDisplayArgs{&info.transform, info.isSecure};
-                                 });
-
-        outWindowInfos.push_back(layer->fillInputInfo(opt.value_or(Layer::InputDisplayArgs{})));
-    });
+            outWindowInfos.push_back(layer->fillInputInfo(opt.value_or(Layer::InputDisplayArgs{})));
+        });
+    }
 
     sNumWindowInfos = outWindowInfos.size();
 
@@ -3602,17 +3696,9 @@
             refreshArgs.outputs.push_back(display->getCompositionDisplay());
         }
     }
-
-    std::vector<LayerSnapshotGuard> layerSnapshotGuards;
-    mDrawingState.traverse([&layerSnapshotGuards](Layer* layer) {
-        if (layer->getLayerSnapshot()->compositionType ==
-            aidl::android::hardware::graphics::composer3::Composition::CURSOR) {
-            layer->updateSnapshot(false /* updateGeometry */);
-            layerSnapshotGuards.emplace_back(layer);
-        }
-    });
-
+    auto layers = moveSnapshotsToCompositionArgs(refreshArgs, /*cursorOnly=*/true, 0);
     mCompositionEngine->updateCursorAsync(refreshArgs);
+    moveSnapshotsFromCompositionArgs(refreshArgs, layers);
 }
 
 void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest> modeRequests) {
@@ -3787,10 +3873,10 @@
     }
 }
 
-void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) {
+void SurfaceFlinger::invalidateLayerStack(const ui::LayerFilter& layerFilter, const Region& dirty) {
     for (const auto& [token, displayDevice] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
         auto display = displayDevice->getCompositionDisplay();
-        if (display->includesLayer(layer->getOutputFilter())) {
+        if (display->includesLayer(layerFilter)) {
             display->editState().dirtyRegion.orSelf(dirty);
         }
     }
@@ -3910,6 +3996,7 @@
     {
         std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
         mCreatedLayers.emplace_back(layer, parent, args.addToRoot);
+        mNewLayers.emplace_back(std::make_unique<frontend::RequestedLayerState>(args));
     }
 
     setTransactionFlags(eTransactionNeeded);
@@ -4260,9 +4347,11 @@
                                            const std::vector<ListenerCallbacks>& listenerCallbacks,
                                            int originPid, int originUid, uint64_t transactionId) {
     uint32_t transactionFlags = 0;
-    for (DisplayState& display : displays) {
-        display.sanitize(permissions);
-        transactionFlags |= setDisplayStateLocked(display);
+    if (!mLayerLifecycleManagerEnabled) {
+        for (DisplayState& display : displays) {
+            display.sanitize(permissions);
+            transactionFlags |= setDisplayStateLocked(display);
+        }
     }
 
     // start and end registration for listeners w/ no surface so they can get their callback.  Note
@@ -4274,9 +4363,16 @@
 
     uint32_t clientStateFlags = 0;
     for (auto& resolvedState : states) {
-        clientStateFlags |=
-                setClientStateLocked(frameTimelineInfo, resolvedState, desiredPresentTime,
-                                     isAutoTimestamp, postTime, permissions, transactionId);
+        if (mLegacyFrontEndEnabled) {
+            clientStateFlags |=
+                    setClientStateLocked(frameTimelineInfo, resolvedState, desiredPresentTime,
+                                         isAutoTimestamp, postTime, permissions, transactionId);
+
+        } else /*mLayerLifecycleManagerEnabled*/ {
+            clientStateFlags |= updateLayerCallbacksAndStats(frameTimelineInfo, resolvedState,
+                                                             desiredPresentTime, isAutoTimestamp,
+                                                             postTime, permissions, transactionId);
+        }
         if ((flags & eAnimation) && resolvedState.state.surface) {
             if (const auto layer = LayerHandle::getLayer(resolvedState.state.surface)) {
                 using LayerUpdateType = scheduler::LayerHistory::LayerUpdateType;
@@ -4309,8 +4405,8 @@
 
     bool needsTraversal = false;
     if (transactionFlags) {
-        // We are on the main thread, we are about to preform a traversal. Clear the traversal bit
-        // so we don't have to wake up again next frame to preform an unnecessary traversal.
+        // We are on the main thread, we are about to perform a traversal. Clear the traversal bit
+        // so we don't have to wake up again next frame to perform an unnecessary traversal.
         if (transactionFlags & eTraversalNeeded) {
             transactionFlags = transactionFlags & (~eTraversalNeeded);
             needsTraversal = true;
@@ -4323,6 +4419,42 @@
     return needsTraversal;
 }
 
+bool SurfaceFlinger::applyAndCommitDisplayTransactionStates(
+        std::vector<TransactionState>& transactions) {
+    Mutex::Autolock _l(mStateLock);
+    bool needsTraversal = false;
+    uint32_t transactionFlags = 0;
+    for (auto& transaction : transactions) {
+        for (DisplayState& display : transaction.displays) {
+            display.sanitize(transaction.permissions);
+            transactionFlags |= setDisplayStateLocked(display);
+        }
+    }
+
+    if (transactionFlags) {
+        // We are on the main thread, we are about to perform a traversal. Clear the traversal bit
+        // so we don't have to wake up again next frame to perform an unnecessary traversal.
+        if (transactionFlags & eTraversalNeeded) {
+            transactionFlags = transactionFlags & (~eTraversalNeeded);
+            needsTraversal = true;
+        }
+        if (transactionFlags) {
+            setTransactionFlags(transactionFlags);
+        }
+    }
+
+    mFrontEndDisplayInfosChanged = mTransactionFlags & eDisplayTransactionNeeded;
+    if (mFrontEndDisplayInfosChanged && !mLegacyFrontEndEnabled) {
+        processDisplayChangesLocked();
+        mFrontEndDisplayInfos.clear();
+        for (const auto& [_, display] : mDisplays) {
+            mFrontEndDisplayInfos.try_emplace(display->getLayerStack(), display->getFrontEndInfo());
+        }
+    }
+
+    return needsTraversal;
+}
+
 uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) {
     const ssize_t index = mCurrentState.displays.indexOfKey(s.token);
     if (index < 0) return 0;
@@ -4704,7 +4836,11 @@
                                           s.trustedPresentationListener);
     }
 
-    if (layer->setTransactionCompletedListeners(callbackHandles)) flags |= eTraversalNeeded;
+    if (layer->setTransactionCompletedListeners(callbackHandles,
+                                                layer->willPresentCurrentTransaction())) {
+        flags |= eTraversalNeeded;
+    }
+
     // Do not put anything that updates layer state or modifies flags after
     // setTransactionCompletedListener
 
@@ -4717,6 +4853,94 @@
     return flags;
 }
 
+uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& frameTimelineInfo,
+                                                      ResolvedComposerState& composerState,
+                                                      int64_t desiredPresentTime,
+                                                      bool isAutoTimestamp, int64_t postTime,
+                                                      uint32_t permissions,
+                                                      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) {
+        // Starts a registration but separates the callback ids according to callback type. This
+        // allows the callback invoker to send on latch callbacks earlier.
+        // note that startRegistration will not re-register if the listener has
+        // already be registered for a prior surface control
+
+        ListenerCallbacks onCommitCallbacks = listener.filter(CallbackId::Type::ON_COMMIT);
+        if (!onCommitCallbacks.callbackIds.empty()) {
+            filteredListeners.push_back(onCommitCallbacks);
+        }
+
+        ListenerCallbacks onCompleteCallbacks = listener.filter(CallbackId::Type::ON_COMPLETE);
+        if (!onCompleteCallbacks.callbackIds.empty()) {
+            filteredListeners.push_back(onCompleteCallbacks);
+        }
+    }
+
+    const uint64_t what = s.what;
+    uint32_t flags = 0;
+    sp<Layer> layer = nullptr;
+    if (s.surface) {
+        layer = LayerHandle::getLayer(s.surface);
+    } else {
+        // The client may provide us a null handle. Treat it as if the layer was removed.
+        ALOGW("Attempt to set client state with a null layer handle");
+    }
+    if (layer == nullptr) {
+        for (auto& [listener, callbackIds] : s.listeners) {
+            mTransactionCallbackInvoker.registerUnpresentedCallbackHandle(
+                    sp<CallbackHandle>::make(listener, callbackIds, s.surface));
+        }
+        return 0;
+    }
+    if (what & layer_state_t::eProducerDisconnect) {
+        layer->onDisconnect();
+    }
+    std::optional<nsecs_t> dequeueBufferTimestamp;
+    if (what & layer_state_t::eMetadataChanged) {
+        dequeueBufferTimestamp = s.metadata.getInt64(gui::METADATA_DEQUEUE_TIME);
+    }
+
+    std::vector<sp<CallbackHandle>> callbackHandles;
+    if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!filteredListeners.empty())) {
+        for (auto& [listener, callbackIds] : filteredListeners) {
+            callbackHandles.emplace_back(
+                    sp<CallbackHandle>::make(listener, callbackIds, s.surface));
+        }
+    }
+    if (what & layer_state_t::eSidebandStreamChanged) {
+        if (layer->setSidebandStream(s.sidebandStream)) flags |= eTraversalNeeded;
+    }
+    if (what & layer_state_t::eBufferChanged) {
+        if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime,
+                             desiredPresentTime, isAutoTimestamp, dequeueBufferTimestamp,
+                             frameTimelineInfo)) {
+            layer->latchBuffer(unused, latchTime);
+            flags |= eTraversalNeeded;
+        }
+        mLayersWithQueuedFrames.emplace(layer);
+    } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
+        layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime);
+    }
+
+    if (what & layer_state_t::eTrustedPresentationInfoChanged) {
+        layer->setTrustedPresentationInfo(s.trustedPresentationThresholds,
+                                          s.trustedPresentationListener);
+    }
+
+    const auto& snapshot = mLayerSnapshotBuilder.getSnapshot(layer->getSequence());
+    bool willPresentCurrentTransaction =
+            snapshot && (snapshot->hasReadyFrame || snapshot->sidebandStreamHasFrame);
+    if (layer->setTransactionCompletedListeners(callbackHandles, willPresentCurrentTransaction))
+        flags |= eTraversalNeeded;
+    return flags;
+}
+
 uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& inputWindowCommands) {
     bool hasChanges = mInputWindowCommands.merge(inputWindowCommands);
     return hasChanges ? eTraversalNeeded : 0;
@@ -4785,6 +5009,7 @@
         LayerCreationArgs mirrorArgs(args);
         mirrorArgs.flags |= ISurfaceComposerClient::eNoColorFill;
         mirrorArgs.addToRoot = true;
+        mirrorArgs.layerStackToMirror = layerStack;
         result = createEffectLayer(mirrorArgs, &outResult.handle, &rootMirrorLayer);
         outResult.layerId = rootMirrorLayer->sequence;
         outResult.layerName = String16(rootMirrorLayer->getDebugName());
@@ -4887,7 +5112,12 @@
     setTransactionFlags(eTransactionNeeded);
 }
 
-void SurfaceFlinger::onHandleDestroyed(BBinder* handle, sp<Layer>& layer, uint32_t /* layerId */) {
+void SurfaceFlinger::onHandleDestroyed(BBinder* handle, sp<Layer>& layer, uint32_t layerId) {
+    {
+        std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
+        mDestroyedHandles.emplace_back(layerId);
+    }
+
     Mutex::Autolock lock(mStateLock);
     markLayerPendingRemovalLocked(layer);
     mBufferCountTracker.remove(handle);
@@ -4895,6 +5125,8 @@
     if (mTransactionTracing) {
         mTransactionTracing->onHandleRemoved(handle);
     }
+
+    setTransactionFlags(eTransactionFlushNeeded);
 }
 
 void SurfaceFlinger::onInitializeDisplays() {
@@ -6458,10 +6690,15 @@
                                          args.useIdentityTransform, args.captureSecureLayers);
     });
 
-    auto traverseLayers = [this, args, layerStack](const LayerVector::Visitor& visitor) {
-        traverseLayersInLayerStack(layerStack, args.uid, visitor);
-    };
-    auto getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
+    GetLayerSnapshotsFunction getLayerSnapshots;
+    if (mLayerLifecycleManagerEnabled) {
+        getLayerSnapshots = getLayerSnapshotsForScreenshots(layerStack, args.uid);
+    } else {
+        auto traverseLayers = [this, args, layerStack](const LayerVector::Visitor& visitor) {
+            traverseLayersInLayerStack(layerStack, args.uid, visitor);
+        };
+        getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
+    }
 
     auto future = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize,
                                       args.pixelFormat, args.allowProtected, args.grayscale,
@@ -6495,10 +6732,15 @@
                                          false /* captureSecureLayers */);
     });
 
-    auto traverseLayers = [this, layerStack](const LayerVector::Visitor& visitor) {
-        traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, visitor);
-    };
-    auto getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
+    GetLayerSnapshotsFunction getLayerSnapshots;
+    if (mLayerLifecycleManagerEnabled) {
+        getLayerSnapshots = getLayerSnapshotsForScreenshots(layerStack, CaptureArgs::UNSET_UID);
+    } else {
+        auto traverseLayers = [this, layerStack](const LayerVector::Visitor& visitor) {
+            traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, visitor);
+        };
+        getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
+    }
 
     if (captureListener == nullptr) {
         ALOGE("capture screen must provide a capture listener callback");
@@ -6593,29 +6835,37 @@
         return std::make_unique<LayerRenderArea>(*this, parent, crop, reqSize, dataspace,
                                                  childrenOnly, args.captureSecureLayers);
     });
-
-    auto traverseLayers = [parent, args, excludeLayerIds](const LayerVector::Visitor& visitor) {
-        parent->traverseChildrenInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
-            if (!layer->isVisible()) {
-                return;
-            } else if (args.childrenOnly && layer == parent.get()) {
-                return;
-            } else if (args.uid != CaptureArgs::UNSET_UID && args.uid != layer->getOwnerUid()) {
-                return;
-            }
-
-            auto p = sp<Layer>::fromExisting(layer);
-            while (p != nullptr) {
-                if (excludeLayerIds.count(p->sequence) != 0) {
+    GetLayerSnapshotsFunction getLayerSnapshots;
+    if (mLayerLifecycleManagerEnabled) {
+        FloatRect parentCrop = crop.isEmpty() ? FloatRect(0, 0, reqSize.width, reqSize.height)
+                                              : crop.toFloatRect();
+        getLayerSnapshots = getLayerSnapshotsForScreenshots(parent->sequence, args.uid,
+                                                            std::move(excludeLayerIds),
+                                                            args.childrenOnly, parentCrop);
+    } else {
+        auto traverseLayers = [parent, args, excludeLayerIds](const LayerVector::Visitor& visitor) {
+            parent->traverseChildrenInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
+                if (!layer->isVisible()) {
+                    return;
+                } else if (args.childrenOnly && layer == parent.get()) {
+                    return;
+                } else if (args.uid != CaptureArgs::UNSET_UID && args.uid != layer->getOwnerUid()) {
                     return;
                 }
-                p = p->getParent();
-            }
 
-            visitor(layer);
-        });
-    };
-    auto getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
+                auto p = sp<Layer>::fromExisting(layer);
+                while (p != nullptr) {
+                    if (excludeLayerIds.count(p->sequence) != 0) {
+                        return;
+                    }
+                    p = p->getParent();
+                }
+
+                visitor(layer);
+            });
+        };
+        getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
+    }
 
     if (captureListener == nullptr) {
         ALOGE("capture screen must provide a capture listener callback");
@@ -7397,24 +7647,18 @@
     return true;
 }
 
-bool SurfaceFlinger::commitCreatedLayers(VsyncId vsyncId) {
-    std::vector<LayerCreatedState> createdLayers;
-    {
-        std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
-        createdLayers = std::move(mCreatedLayers);
-        mCreatedLayers.clear();
-        if (createdLayers.size() == 0) {
-            return false;
-        }
+bool SurfaceFlinger::commitCreatedLayers(VsyncId vsyncId,
+                                         std::vector<LayerCreatedState>& createdLayers) {
+    if (createdLayers.size() == 0) {
+        return false;
     }
 
     Mutex::Autolock _l(mStateLock);
     for (const auto& createdLayer : createdLayers) {
         handleLayerCreatedLocked(createdLayer, vsyncId);
     }
-    createdLayers.clear();
     mLayersAdded = true;
-    return true;
+    return mLayersAdded;
 }
 
 void SurfaceFlinger::updateLayerMetadataSnapshot() {
@@ -7442,6 +7686,150 @@
     });
 }
 
+void SurfaceFlinger::moveSnapshotsFromCompositionArgs(
+        compositionengine::CompositionRefreshArgs& refreshArgs,
+        std::vector<std::pair<Layer*, LayerFE*>>& layers) {
+    if (mLayerLifecycleManagerEnabled) {
+        std::vector<std::unique_ptr<frontend::LayerSnapshot>>& snapshots =
+                mLayerSnapshotBuilder.getSnapshots();
+        for (auto [_, layerFE] : layers) {
+            auto i = layerFE->mSnapshot->globalZ;
+            snapshots[i] = std::move(layerFE->mSnapshot);
+        }
+    }
+    if (mLegacyFrontEndEnabled && !mLayerLifecycleManagerEnabled) {
+        for (auto [layer, layerFE] : layers) {
+            layer->updateLayerSnapshot(std::move(layerFE->mSnapshot));
+        }
+    }
+}
+
+std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToCompositionArgs(
+        compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly, int64_t vsyncId) {
+    std::vector<std::pair<Layer*, LayerFE*>> layers;
+    if (mLayerLifecycleManagerEnabled) {
+        mLayerSnapshotBuilder.forEachVisibleSnapshot(
+                [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) {
+                    if (cursorOnly &&
+                        snapshot->compositionType !=
+                                aidl::android::hardware::graphics::composer3::Composition::CURSOR) {
+                        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 = legacyLayer->getCompositionEngineLayerFE(snapshot->path);
+                    layerFE->mSnapshot = std::move(snapshot);
+                    refreshArgs.layers.push_back(layerFE);
+                    layers.emplace_back(legacyLayer.get(), layerFE.get());
+                });
+    }
+    if (mLegacyFrontEndEnabled && !mLayerLifecycleManagerEnabled) {
+        mDrawingState.traverseInZOrder([&refreshArgs, cursorOnly, &layers](Layer* layer) {
+            if (auto layerFE = layer->getCompositionEngineLayerFE()) {
+                if (cursorOnly &&
+                    layer->getLayerSnapshot()->compositionType !=
+                            aidl::android::hardware::graphics::composer3::Composition::CURSOR)
+                    return;
+                layer->updateSnapshot(/* refreshArgs.updatingGeometryThisFrame */ true);
+                layerFE->mSnapshot = layer->stealLayerSnapshot();
+                refreshArgs.layers.push_back(layerFE);
+                layers.emplace_back(layer, layerFE.get());
+            }
+        });
+    }
+
+    return layers;
+}
+
+std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
+SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack,
+                                                uint32_t uid) {
+    return [this, 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;
+            }
+
+            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));
+        }
+
+        return layers;
+    };
+}
+
+std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
+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,
+            parentCrop]() {
+        frontend::LayerSnapshotBuilder::Args
+                args{.root = mLayerHierarchyBuilder.getPartialHierarchy(rootLayerId, childrenOnly),
+                     .layerLifecycleManager = mLayerLifecycleManager,
+                     .displays = mFrontEndDisplayInfos,
+                     .displayChanges = true,
+                     .globalShadowSettings = mDrawingState.globalShadowSettings,
+                     .supportsBlur = mSupportsBlur,
+                     .forceFullDamage = mForceFullDamage,
+                     .parentCrop = {parentCrop},
+                     .excludeLayerIds = std::move(excludeLayerIds)};
+        mLayerSnapshotBuilder.update(args);
+
+        auto getLayerSnapshotsFn = getLayerSnapshotsForScreenshots({}, uid);
+        std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
+        args.root = mLayerHierarchyBuilder.getHierarchy();
+        args.parentCrop.reset();
+        args.excludeLayerIds.clear();
+        mLayerSnapshotBuilder.update(args);
+        return layers;
+    };
+}
+
+SurfaceFlinger::LifecycleUpdate SurfaceFlinger::flushLifecycleUpdates() {
+    LifecycleUpdate update;
+    ATRACE_NAME("TransactionHandler:flushTransactions");
+    // Locking:
+    // 1. to prevent onHandleDestroyed from being called while the state lock is held,
+    // we must keep a copy of the transactions (specifically the composer
+    // states) around outside the scope of the lock.
+    // 2. Transactions and created layers do not share a lock. To prevent applying
+    // transactions with layers still in the createdLayer queue, flush the transactions
+    // before committing the created layers.
+    update.transactions = mTransactionHandler.flushTransactions();
+    {
+        // TODO(b/238781169) lockless queue this and keep order.
+        std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
+        update.layerCreatedStates = std::move(mCreatedLayers);
+        mCreatedLayers.clear();
+        update.newLayers = std::move(mNewLayers);
+        mNewLayers.clear();
+        update.destroyedHandles = std::move(mDestroyedHandles);
+        mDestroyedHandles.clear();
+    }
+    return update;
+}
+
 // gui::ISurfaceComposer
 
 binder::Status SurfaceComposerAIDL::bootFinished() {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 1eb1fda..09891be 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -71,7 +71,9 @@
 #include "FlagManager.h"
 #include "FrontEnd/DisplayInfo.h"
 #include "FrontEnd/LayerCreationArgs.h"
+#include "FrontEnd/LayerLifecycleManager.h"
 #include "FrontEnd/LayerSnapshot.h"
+#include "FrontEnd/LayerSnapshotBuilder.h"
 #include "FrontEnd/TransactionHandler.h"
 #include "LayerVector.h"
 #include "Scheduler/ISchedulerCallback.h"
@@ -450,6 +452,26 @@
         FINISHED,
     };
 
+    struct LayerCreatedState {
+        LayerCreatedState(const wp<Layer>& layer, const wp<Layer>& parent, bool addToRoot)
+              : layer(layer), initialParent(parent), addToRoot(addToRoot) {}
+        wp<Layer> layer;
+        // Indicates the initial parent of the created layer, only used for creating layer in
+        // SurfaceFlinger. If nullptr, it may add the created layer into the current root layers.
+        wp<Layer> initialParent;
+        // Indicates whether the layer getting created should be added at root if there's no parent
+        // and has permission ACCESS_SURFACE_FLINGER. If set to false and no parent, the layer will
+        // be added offscreen.
+        bool addToRoot;
+    };
+
+    struct LifecycleUpdate {
+        std::vector<TransactionState> transactions;
+        std::vector<LayerCreatedState> layerCreatedStates;
+        std::vector<std::unique_ptr<frontend::RequestedLayerState>> newLayers;
+        std::vector<uint32_t> destroyedHandles;
+    };
+
     template <typename F, std::enable_if_t<!std::is_member_function_pointer_v<F>>* = nullptr>
     static Dumper dumper(F&& dump) {
         using namespace std::placeholders;
@@ -688,6 +710,17 @@
 
     void updateLayerGeometry();
     void updateLayerMetadataSnapshot();
+    std::vector<std::pair<Layer*, LayerFE*>> moveSnapshotsToCompositionArgs(
+            compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly,
+            int64_t vsyncId);
+    void moveSnapshotsFromCompositionArgs(compositionengine::CompositionRefreshArgs& refreshArgs,
+                                          std::vector<std::pair<Layer*, LayerFE*>>& layers);
+    bool updateLayerSnapshotsLegacy(VsyncId vsyncId, LifecycleUpdate& update,
+                                    bool transactionsFlushed, bool& out)
+            REQUIRES(kMainThreadContext);
+    bool updateLayerSnapshots(VsyncId vsyncId, LifecycleUpdate& update, bool transactionsFlushed,
+                              bool& out) REQUIRES(kMainThreadContext);
+    LifecycleUpdate flushLifecycleUpdates() REQUIRES(kMainThreadContext);
 
     void updateInputFlinger();
     void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext);
@@ -715,6 +748,8 @@
     bool flushTransactionQueues(VsyncId) REQUIRES(kMainThreadContext);
 
     bool applyTransactions(std::vector<TransactionState>&, VsyncId) REQUIRES(kMainThreadContext);
+    bool applyAndCommitDisplayTransactionStates(std::vector<TransactionState>& transactions)
+            REQUIRES(kMainThreadContext);
 
     // Returns true if there is at least one transaction that needs to be flushed
     bool transactionFlushNeeded();
@@ -730,7 +765,10 @@
                                   int64_t desiredPresentTime, bool isAutoTimestamp,
                                   int64_t postTime, uint32_t permissions, uint64_t transactionId)
             REQUIRES(mStateLock);
-
+    uint32_t updateLayerCallbacksAndStats(const FrameTimelineInfo&, ResolvedComposerState&,
+                                          int64_t desiredPresentTime, bool isAutoTimestamp,
+                                          int64_t postTime, uint32_t permissions,
+                                          uint64_t transactionId) REQUIRES(mStateLock);
     uint32_t getTransactionFlags() const;
 
     // Sets the masked bits, and schedules a commit if needed.
@@ -888,7 +926,7 @@
 
     // mark a region of a layer stack dirty. this updates the dirty
     // region of all screens presenting this layer stack.
-    void invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty);
+    void invalidateLayerStack(const ui::LayerFilter& layerFilter, const Region& dirty);
 
     ui::LayerFilter makeLayerFilterForDisplay(DisplayId displayId, ui::LayerStack layerStack)
             REQUIRES(mStateLock) {
@@ -1154,6 +1192,7 @@
     // Set if LayerMetadata has changed since the last LayerMetadata snapshot.
     bool mLayerMetadataSnapshotNeeded = false;
 
+    // TODO(b/238781169) validate these on composition
     // Tracks layers that have pending frames which are candidates for being
     // latched.
     std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithQueuedFrames;
@@ -1325,23 +1364,11 @@
             GUARDED_BY(mStateLock);
 
     mutable std::mutex mCreatedLayersLock;
-    struct LayerCreatedState {
-        LayerCreatedState(const wp<Layer>& layer, const wp<Layer> parent, bool addToRoot)
-              : layer(layer), initialParent(parent), addToRoot(addToRoot) {}
-        wp<Layer> layer;
-        // Indicates the initial parent of the created layer, only used for creating layer in
-        // SurfaceFlinger. If nullptr, it may add the created layer into the current root layers.
-        wp<Layer> initialParent;
-        // Indicates whether the layer getting created should be added at root if there's no parent
-        // and has permission ACCESS_SURFACE_FLINGER. If set to false and no parent, the layer will
-        // be added offscreen.
-        bool addToRoot;
-    };
 
     // A temporay pool that store the created layers and will be added to current state in main
     // thread.
     std::vector<LayerCreatedState> mCreatedLayers GUARDED_BY(mCreatedLayersLock);
-    bool commitCreatedLayers(VsyncId);
+    bool commitCreatedLayers(VsyncId, std::vector<LayerCreatedState>& createdLayers);
     void handleLayerCreatedLocked(const LayerCreatedState&, VsyncId) REQUIRES(mStateLock);
 
     mutable std::mutex mMirrorDisplayLock;
@@ -1363,6 +1390,11 @@
         return hasDisplay(
                 [](const auto& display) { return display.isRefreshRateOverlayEnabled(); });
     }
+    std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> getLayerSnapshotsForScreenshots(
+            std::optional<ui::LayerStack> layerStack, uint32_t uid);
+    std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> getLayerSnapshotsForScreenshots(
+            uint32_t rootLayerId, uint32_t uid, std::unordered_set<uint32_t> excludeLayerIds,
+            bool childrenOnly, const FloatRect& parentCrop);
 
     const sp<WindowInfosListenerInvoker> mWindowInfosListenerInvoker;
 
@@ -1375,6 +1407,18 @@
 
     bool mPowerHintSessionEnabled;
 
+    bool mLayerLifecycleManagerEnabled = false;
+    bool mLegacyFrontEndEnabled = true;
+
+    frontend::LayerLifecycleManager mLayerLifecycleManager;
+    frontend::LayerHierarchyBuilder mLayerHierarchyBuilder{{}};
+    frontend::LayerSnapshotBuilder mLayerSnapshotBuilder;
+
+    std::vector<uint32_t> mDestroyedHandles;
+    std::vector<std::unique_ptr<frontend::RequestedLayerState>> mNewLayers;
+    // These classes do not store any client state but help with managing transaction callbacks
+    // and stats.
+    std::unordered_map<uint32_t, sp<Layer>> mLegacyLayers;
     struct {
         bool late = false;
         bool early = false;
@@ -1382,6 +1426,7 @@
 
     TransactionHandler mTransactionHandler;
     display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> mFrontEndDisplayInfos;
+    bool mFrontEndDisplayInfosChanged = false;
 };
 
 class SurfaceComposerAIDL : public gui::BnSurfaceComposer {
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
index 11719c4..c088e7b 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
@@ -148,7 +148,7 @@
     layer->fenceHasSignaled();
     layer->onPreComposition(mFdp.ConsumeIntegral<int64_t>());
     const std::vector<sp<CallbackHandle>> callbacks;
-    layer->setTransactionCompletedListeners(callbacks);
+    layer->setTransactionCompletedListeners(callbacks, mFdp.ConsumeBool());
 
     std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared<
             renderengine::mock::FakeExternalTexture>(mFdp.ConsumeIntegral<uint32_t>(),