Merge "Add input flag enable_per_device_input_latency_metrics" into main
diff --git a/cmds/installd/otapreopt_script.sh b/cmds/installd/otapreopt_script.sh
index 28bd793..b7ad331 100644
--- a/cmds/installd/otapreopt_script.sh
+++ b/cmds/installd/otapreopt_script.sh
@@ -50,6 +50,37 @@
   exit 1
 fi
 
+# A source that infinitely emits arbitrary lines.
+# When connected to STDIN of another process, this source keeps STDIN open until
+# the consumer process closes STDIN or this script dies.
+function infinite_source {
+  while echo .; do
+    sleep 1
+  done
+}
+
+PR_DEXOPT_JOB_VERSION="$(pm art pr-dexopt-job --version)"
+if (( $? == 0 )) && (( $PR_DEXOPT_JOB_VERSION >= 3 )); then
+  # Delegate to Pre-reboot Dexopt, a feature of ART Service.
+  # ART Service decides what to do with this request:
+  # - If Pre-reboot Dexopt is disabled or unsupported, the command returns
+  #   non-zero. This is always the case if the current system is Android 14 or
+  #   earlier.
+  # - If Pre-reboot Dexopt is enabled in synchronous mode, the command blocks
+  #   until Pre-reboot Dexopt finishes, and returns zero no matter it succeeds or
+  #   not. This is the default behavior if the current system is Android 15.
+  # - If Pre-reboot Dexopt is enabled in asynchronous mode, the command schedules
+  #   an asynchronous job and returns 0 immediately. The job will then run by the
+  #   job scheduler when the device is idle and charging.
+  if infinite_source | pm art on-ota-staged --slot "$TARGET_SLOT_SUFFIX"; then
+    # Handled by Pre-reboot Dexopt.
+    exit 0
+  fi
+  echo "Pre-reboot Dexopt not enabled. Fall back to otapreopt."
+else
+  echo "Pre-reboot Dexopt is too old. Fall back to otapreopt."
+fi
+
 if [ "$(/system/bin/otapreopt_chroot --version)" != 2 ]; then
   # We require an updated chroot wrapper that reads dexopt commands from stdin.
   # Even if we kept compat with the old binary, the OTA preopt wouldn't work due
diff --git a/include/input/Input.h b/include/input/Input.h
index 1a3cb6a..a8684bd 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -251,6 +251,8 @@
     TOUCH_MODE = AINPUT_EVENT_TYPE_TOUCH_MODE,
     ftl_first = KEY,
     ftl_last = TOUCH_MODE,
+    // Used by LatencyTracker fuzzer
+    kMaxValue = ftl_last
 };
 
 std::string inputEventSourceToString(int32_t source);
diff --git a/libs/adbd_auth/adbd_auth.cpp b/libs/adbd_auth/adbd_auth.cpp
index 78896ed..d31cb3d 100644
--- a/libs/adbd_auth/adbd_auth.cpp
+++ b/libs/adbd_auth/adbd_auth.cpp
@@ -390,13 +390,16 @@
         }
     }
 
-    static constexpr const char* key_paths[] = {"/adb_keys", "/data/misc/adb/adb_keys"};
+    static constexpr std::pair<const char*, bool> key_paths[] = {
+        {"/adb_keys",               true  /* follow symlinks */       },
+        {"/data/misc/adb/adb_keys", false /* don't follow symlinks */ },
+    };
     void IteratePublicKeys(bool (*callback)(void*, const char*, size_t), void* opaque) {
-        for (const auto& path : key_paths) {
+        for (const auto& [path, follow_symlinks] : key_paths) {
             if (access(path, R_OK) == 0) {
                 LOG(INFO) << "adbd_auth: loading keys from " << path;
                 std::string content;
-                if (!android::base::ReadFileToString(path, &content)) {
+                if (!android::base::ReadFileToString(path, &content, follow_symlinks)) {
                     PLOG(ERROR) << "adbd_auth: couldn't read " << path;
                     continue;
                 }
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 9578713..1e463a4 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -888,6 +888,7 @@
             enabled: false,
         },
     },
+    corpus: ["corpus/*"],
     fuzz_config: {
         cc: [
             "smoreland@google.com",
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index f8e3fd0..b8d2b5f 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -504,13 +504,7 @@
                  callbackId.to_string().c_str());
         return;
     }
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
-    if (!it->second.disconnectedAfterAcquired) {
-        mNumAcquired--;
-    }
-#else
     mNumAcquired--;
-#endif
     BBQ_TRACE("frame=%" PRIu64, callbackId.framenumber);
     BQA_LOGV("released %s", callbackId.to_string().c_str());
     mBufferItemConsumer->releaseBuffer(it->second, releaseFence);
@@ -561,7 +555,7 @@
         applyTransaction = false;
     }
 
-    BLASTBufferItem bufferItem;
+    BufferItem bufferItem;
 
     status_t status =
             mBufferItemConsumer->acquireBuffer(&bufferItem, 0 /* expectedPresent */, false);
@@ -767,9 +761,6 @@
         }
 
         // add to shadow queue
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
-        mNumDequeued--;
-#endif
         mNumFrameAvailable++;
         if (waitForTransactionCallback && mNumFrameAvailable >= 2) {
             acquireAndReleaseBuffer();
@@ -824,17 +815,8 @@
 };
 
 void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {
-    {
-        std::lock_guard _lock{mTimestampMutex};
-        mDequeueTimestamps.erase(bufferId);
-    }
-
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
-    {
-        std::lock_guard lock{mMutex};
-        mNumDequeued--;
-    }
-#endif
+    std::lock_guard _lock{mTimestampMutex};
+    mDequeueTimestamps.erase(bufferId);
 }
 
 bool BLASTBufferQueue::syncNextTransaction(
@@ -1134,116 +1116,6 @@
                                             producerControlledByApp, output);
     }
 
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
-    status_t disconnect(int api, DisconnectMode mode) override {
-        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
-        if (!bbq) {
-            return BufferQueueProducer::disconnect(api, mode);
-        }
-
-        std::lock_guard lock{bbq->mMutex};
-        if (status_t status = BufferQueueProducer::disconnect(api, mode); status != OK) {
-            return status;
-        }
-
-        // We need to reset dequeued and acquired counts because BufferQueueProducer::disconnect
-        // calls BufferQueueCore::freeAllBuffersLocked which frees all dequeued and acquired
-        // buffers. We don't reset mNumFrameAvailable because these buffers are still available
-        // in BufferItemConsumer.
-        bbq->mNumDequeued = 0;
-        bbq->mNumAcquired = 0;
-        // SurfaceFlinger sends release callbacks for buffers that have been acquired after a
-        // disconnect. We set disconnectedAfterAcquired to true so that we can ignore any stale
-        // releases that come in after the producer is disconnected. Otherwise, releaseBuffer will
-        // decrement mNumAcquired for a buffer that was acquired before we reset mNumAcquired to
-        // zero.
-        for (auto& [releaseId, bufferItem] : bbq->mSubmitted) {
-            bufferItem.disconnectedAfterAcquired = true;
-        }
-
-        return OK;
-    }
-
-    status_t setAsyncMode(bool asyncMode) override {
-        if (status_t status = BufferQueueProducer::setAsyncMode(asyncMode); status != OK) {
-            return status;
-        }
-
-        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
-        if (!bbq) {
-            return OK;
-        }
-
-        {
-            std::lock_guard lock{bbq->mMutex};
-            bbq->mAsyncMode = asyncMode;
-        }
-
-        return OK;
-    }
-
-    status_t setSharedBufferMode(bool sharedBufferMode) override {
-        if (status_t status = BufferQueueProducer::setSharedBufferMode(sharedBufferMode);
-            status != OK) {
-            return status;
-        }
-
-        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
-        if (!bbq) {
-            return OK;
-        }
-
-        {
-            std::lock_guard lock{bbq->mMutex};
-            bbq->mSharedBufferMode = sharedBufferMode;
-        }
-
-        return OK;
-    }
-
-    status_t detachBuffer(int slot) override {
-        if (status_t status = BufferQueueProducer::detachBuffer(slot); status != OK) {
-            return status;
-        }
-
-        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
-        if (!bbq) {
-            return OK;
-        }
-
-        {
-            std::lock_guard lock{bbq->mMutex};
-            bbq->mNumDequeued--;
-        }
-
-        return OK;
-    }
-
-    status_t dequeueBuffer(int* outSlot, sp<Fence>* outFence, uint32_t width, uint32_t height,
-                           PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
-                           FrameEventHistoryDelta* outTimestamps) override {
-        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
-        if (!bbq) {
-            return BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format,
-                                                      usage, outBufferAge, outTimestamps);
-        }
-
-        {
-            std::lock_guard lock{bbq->mMutex};
-            bbq->mNumDequeued++;
-        }
-
-        status_t status =
-                BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format, usage,
-                                                   outBufferAge, outTimestamps);
-        if (status < 0) {
-            std::lock_guard lock{bbq->mMutex};
-            bbq->mNumDequeued--;
-        }
-        return status;
-    }
-#endif
-
     // We want to resize the frame history when changing the size of the buffer queue
     status_t setMaxDequeuedBufferCount(int maxDequeuedBufferCount) override {
         int maxBufferCount;
@@ -1266,13 +1138,6 @@
             bbq->resizeFrameEventHistory(newFrameHistorySize);
         }
 
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
-        {
-            std::lock_guard lock{bbq->mMutex};
-            bbq->mMaxDequeuedBuffers = maxDequeuedBufferCount;
-        }
-#endif
-
         return OK;
     }
 
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 729d46a..0e7dd20 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -187,15 +187,6 @@
     // BufferQueue internally allows 1 more than
     // the max to be acquired
     int32_t mMaxAcquiredBuffers GUARDED_BY(mMutex) = 1;
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
-    int32_t mMaxDequeuedBuffers GUARDED_BY(mMutex) = 1;
-    static constexpr int32_t kMaxBufferCount = BufferQueueDefs::NUM_BUFFER_SLOTS;
-
-    bool mAsyncMode GUARDED_BY(mMutex) = false;
-    bool mSharedBufferMode GUARDED_BY(mMutex) = false;
-
-    int32_t mNumDequeued GUARDED_BY(mMutex) = 0;
-#endif
     int32_t mNumFrameAvailable GUARDED_BY(mMutex) = 0;
     int32_t mNumAcquired GUARDED_BY(mMutex) = 0;
 
@@ -204,16 +195,9 @@
     // latch stale buffers and that we don't wait on barriers from an old producer.
     uint32_t mProducerId = 0;
 
-    class BLASTBufferItem : public BufferItem {
-    public:
-        // True if BBQBufferQueueProducer is disconnected after the buffer is acquried but
-        // before it is released.
-        bool disconnectedAfterAcquired{false};
-    };
-
     // Keep a reference to the submitted buffers so we can release when surfaceflinger drops the
     // buffer or the buffer has been presented and a new buffer is ready to be presented.
-    std::unordered_map<ReleaseCallbackId, BLASTBufferItem, ReleaseBufferCallbackIdHash> mSubmitted
+    std::unordered_map<ReleaseCallbackId, BufferItem, ReleaseBufferCallbackIdHash> mSubmitted
             GUARDED_BY(mMutex);
 
     // Keep a queue of the released buffers instead of immediately releasing
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index bcef350..250e72c 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -52,6 +52,7 @@
 #include "Connection.h"
 #include "DebugConfig.h"
 #include "InputDispatcher.h"
+#include "InputEventTimeline.h"
 #include "trace/InputTracer.h"
 #include "trace/InputTracingPerfettoBackend.h"
 #include "trace/ThreadedBackend.h"
@@ -4642,10 +4643,9 @@
         if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
             IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
             !mInputFilterEnabled) {
-            const bool isDown = args.action == AMOTION_EVENT_ACTION_DOWN;
             std::set<InputDeviceUsageSource> sources = getUsageSourcesForMotionArgs(args);
-            mLatencyTracker.trackListener(args.id, isDown, args.eventTime, args.readTime,
-                                          args.deviceId, sources);
+            mLatencyTracker.trackListener(args.id, args.eventTime, args.readTime, args.deviceId,
+                                          sources, args.action, InputEventType::MOTION);
         }
 
         needWake = enqueueInboundEventLocked(std::move(newEntry));
diff --git a/services/inputflinger/dispatcher/InputEventTimeline.cpp b/services/inputflinger/dispatcher/InputEventTimeline.cpp
index a365003..31ceb8d 100644
--- a/services/inputflinger/dispatcher/InputEventTimeline.cpp
+++ b/services/inputflinger/dispatcher/InputEventTimeline.cpp
@@ -68,13 +68,15 @@
 
 InputEventTimeline::InputEventTimeline(bool isDown, nsecs_t eventTime, nsecs_t readTime,
                                        uint16_t vendorId, uint16_t productId,
-                                       const std::set<InputDeviceUsageSource>& sources)
+                                       const std::set<InputDeviceUsageSource>& sources,
+                                       InputEventActionType inputEventActionType)
       : isDown(isDown),
         eventTime(eventTime),
         readTime(readTime),
         vendorId(vendorId),
         productId(productId),
-        sources(sources) {}
+        sources(sources),
+        inputEventActionType(inputEventActionType) {}
 
 bool InputEventTimeline::operator==(const InputEventTimeline& rhs) const {
     if (connectionTimelines.size() != rhs.connectionTimelines.size()) {
@@ -90,7 +92,8 @@
         }
     }
     return isDown == rhs.isDown && eventTime == rhs.eventTime && readTime == rhs.readTime &&
-            vendorId == rhs.vendorId && productId == rhs.productId && sources == rhs.sources;
+            vendorId == rhs.vendorId && productId == rhs.productId && sources == rhs.sources &&
+            inputEventActionType == rhs.inputEventActionType;
 }
 
 } // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputEventTimeline.h b/services/inputflinger/dispatcher/InputEventTimeline.h
index 1756944..6668399 100644
--- a/services/inputflinger/dispatcher/InputEventTimeline.h
+++ b/services/inputflinger/dispatcher/InputEventTimeline.h
@@ -74,15 +74,39 @@
     bool mHasGraphicsTimeline = false;
 };
 
+enum class InputEventActionType : int32_t {
+    UNKNOWN_INPUT_EVENT = 0,
+    MOTION_ACTION_DOWN = 1,
+    // Motion events for ACTION_MOVE (characterizes scrolling motion)
+    MOTION_ACTION_MOVE = 2,
+    // Motion events for ACTION_UP (when the pointer first goes up)
+    MOTION_ACTION_UP = 3,
+    // Motion events for ACTION_HOVER_MOVE (pointer position on screen changes but pointer is not
+    // down)
+    MOTION_ACTION_HOVER_MOVE = 4,
+    // Motion events for ACTION_SCROLL (moving the mouse wheel)
+    MOTION_ACTION_SCROLL = 5,
+    // Key events for both ACTION_DOWN and ACTION_UP (key press and key release)
+    KEY = 6,
+
+    ftl_first = UNKNOWN_INPUT_EVENT,
+    ftl_last = KEY,
+    // Used by latency fuzzer
+    kMaxValue = ftl_last
+
+};
+
 struct InputEventTimeline {
     InputEventTimeline(bool isDown, nsecs_t eventTime, nsecs_t readTime, uint16_t vendorId,
-                       uint16_t productId, const std::set<InputDeviceUsageSource>& sources);
+                       uint16_t productId, const std::set<InputDeviceUsageSource>& sources,
+                       InputEventActionType inputEventActionType);
     const bool isDown; // True if this is an ACTION_DOWN event
     const nsecs_t eventTime;
     const nsecs_t readTime;
     const uint16_t vendorId;
     const uint16_t productId;
     const std::set<InputDeviceUsageSource> sources;
+    const InputEventActionType inputEventActionType;
 
     struct IBinderHash {
         std::size_t operator()(const sp<IBinder>& b) const {
diff --git a/services/inputflinger/dispatcher/LatencyTracker.cpp b/services/inputflinger/dispatcher/LatencyTracker.cpp
index 698bd9f..721d009 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.cpp
+++ b/services/inputflinger/dispatcher/LatencyTracker.cpp
@@ -67,9 +67,10 @@
     LOG_ALWAYS_FATAL_IF(processor == nullptr);
 }
 
-void LatencyTracker::trackListener(int32_t inputEventId, bool isDown, nsecs_t eventTime,
-                                   nsecs_t readTime, DeviceId deviceId,
-                                   const std::set<InputDeviceUsageSource>& sources) {
+void LatencyTracker::trackListener(int32_t inputEventId, nsecs_t eventTime, nsecs_t readTime,
+                                   DeviceId deviceId,
+                                   const std::set<InputDeviceUsageSource>& sources,
+                                   int inputEventAction, InputEventType inputEventType) {
     reportAndPruneMatureRecords(eventTime);
     const auto it = mTimelines.find(inputEventId);
     if (it != mTimelines.end()) {
@@ -101,9 +102,43 @@
         return;
     }
 
+    const InputEventActionType inputEventActionType = [&]() {
+        switch (inputEventType) {
+            case InputEventType::MOTION: {
+                switch (inputEventAction) {
+                    case AMOTION_EVENT_ACTION_DOWN:
+                        return InputEventActionType::MOTION_ACTION_DOWN;
+                    case AMOTION_EVENT_ACTION_MOVE:
+                        return InputEventActionType::MOTION_ACTION_MOVE;
+                    case AMOTION_EVENT_ACTION_UP:
+                        return InputEventActionType::MOTION_ACTION_UP;
+                    case AMOTION_EVENT_ACTION_HOVER_MOVE:
+                        return InputEventActionType::MOTION_ACTION_HOVER_MOVE;
+                    case AMOTION_EVENT_ACTION_SCROLL:
+                        return InputEventActionType::MOTION_ACTION_SCROLL;
+                    default:
+                        return InputEventActionType::UNKNOWN_INPUT_EVENT;
+                }
+            }
+            case InputEventType::KEY: {
+                switch (inputEventAction) {
+                    case AKEY_EVENT_ACTION_DOWN:
+                    case AKEY_EVENT_ACTION_UP:
+                        return InputEventActionType::KEY;
+                    default:
+                        return InputEventActionType::UNKNOWN_INPUT_EVENT;
+                }
+            }
+            default:
+                return InputEventActionType::UNKNOWN_INPUT_EVENT;
+        }
+    }();
+
+    bool isDown = inputEventType == InputEventType::MOTION &&
+            inputEventAction == AMOTION_EVENT_ACTION_DOWN;
     mTimelines.emplace(inputEventId,
                        InputEventTimeline(isDown, eventTime, readTime, identifier->vendor,
-                                          identifier->product, sources));
+                                          identifier->product, sources, inputEventActionType));
     mEventTimes.emplace(eventTime, inputEventId);
 }
 
diff --git a/services/inputflinger/dispatcher/LatencyTracker.h b/services/inputflinger/dispatcher/LatencyTracker.h
index 890d61d..532f422 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.h
+++ b/services/inputflinger/dispatcher/LatencyTracker.h
@@ -52,8 +52,9 @@
      * duplicate events that happen to have the same eventTime and inputEventId. Therefore, we
      * must drop all duplicate data.
      */
-    void trackListener(int32_t inputEventId, bool isDown, nsecs_t eventTime, nsecs_t readTime,
-                       DeviceId deviceId, const std::set<InputDeviceUsageSource>& sources);
+    void trackListener(int32_t inputEventId, nsecs_t eventTime, nsecs_t readTime, DeviceId deviceId,
+                       const std::set<InputDeviceUsageSource>& sources, int inputEventActionType,
+                       InputEventType inputEventType);
     void trackFinishedEvent(int32_t inputEventId, const sp<IBinder>& connectionToken,
                             nsecs_t deliveryTime, nsecs_t consumeTime, nsecs_t finishTime);
     void trackGraphicsLatency(int32_t inputEventId, const sp<IBinder>& connectionToken,
diff --git a/services/inputflinger/tests/LatencyTracker_test.cpp b/services/inputflinger/tests/LatencyTracker_test.cpp
index 4fcffdd..5650286 100644
--- a/services/inputflinger/tests/LatencyTracker_test.cpp
+++ b/services/inputflinger/tests/LatencyTracker_test.cpp
@@ -61,12 +61,13 @@
 
 InputEventTimeline getTestTimeline() {
     InputEventTimeline t(
-            /*isDown=*/true,
+            /*isDown=*/false,
             /*eventTime=*/2,
             /*readTime=*/3,
             /*vendorId=*/0,
             /*productId=*/0,
-            /*sources=*/{InputDeviceUsageSource::UNKNOWN});
+            /*sources=*/{InputDeviceUsageSource::UNKNOWN},
+            /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT);
     ConnectionTimeline expectedCT(/*deliveryTime=*/6, /*consumeTime=*/7, /*finishTime=*/8);
     std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
     graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME] = 9;
@@ -116,9 +117,10 @@
 void LatencyTrackerTest::triggerEventReporting(nsecs_t lastEventTime) {
     const nsecs_t triggerEventTime =
             lastEventTime + std::chrono::nanoseconds(ANR_TIMEOUT).count() + 1;
-    mTracker->trackListener(/*inputEventId=*/1, /*isDown=*/true, triggerEventTime,
+    mTracker->trackListener(/*inputEventId=*/1, triggerEventTime,
                             /*readTime=*/3, DEVICE_ID,
-                            /*sources=*/{InputDeviceUsageSource::UNKNOWN});
+                            /*sources=*/{InputDeviceUsageSource::UNKNOWN},
+                            AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION);
 }
 
 void LatencyTrackerTest::assertReceivedTimeline(const InputEventTimeline& timeline) {
@@ -167,12 +169,15 @@
  * any additional ConnectionTimeline's.
  */
 TEST_F(LatencyTrackerTest, TrackListener_DoesNotTriggerReporting) {
-    mTracker->trackListener(/*inputEventId=*/1, /*isDown=*/false, /*eventTime=*/2,
-                            /*readTime=*/3, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN});
+    mTracker->trackListener(/*inputEventId=*/1, /*eventTime=*/2,
+                            /*readTime=*/3, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN},
+                            AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION);
     triggerEventReporting(/*eventTime=*/2);
-    assertReceivedTimeline(InputEventTimeline{/*isDown=*/false, /*eventTime=*/2,
-                                              /*readTime=*/3, /*vendorId=*/0, /*productID=*/0,
-                                              /*sources=*/{InputDeviceUsageSource::UNKNOWN}});
+    assertReceivedTimeline(
+            InputEventTimeline{/*isDown=*/false, /*eventTime=*/2,
+                               /*readTime=*/3, /*vendorId=*/0, /*productID=*/0,
+                               /*sources=*/{InputDeviceUsageSource::UNKNOWN},
+                               /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT});
 }
 
 /**
@@ -203,8 +208,9 @@
 
     const auto& [connectionToken, expectedCT] = *expected.connectionTimelines.begin();
 
-    mTracker->trackListener(inputEventId, expected.isDown, expected.eventTime, expected.readTime,
-                            DEVICE_ID, {InputDeviceUsageSource::UNKNOWN});
+    mTracker->trackListener(inputEventId, expected.eventTime, expected.readTime, DEVICE_ID,
+                            {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL,
+                            InputEventType::MOTION);
     mTracker->trackFinishedEvent(inputEventId, connectionToken, expectedCT.deliveryTime,
                                  expectedCT.consumeTime, expectedCT.finishTime);
     mTracker->trackGraphicsLatency(inputEventId, connectionToken, expectedCT.graphicsTimeline);
@@ -220,14 +226,16 @@
 TEST_F(LatencyTrackerTest, WhenDuplicateEventsAreReported_DoesNotCrash) {
     constexpr nsecs_t inputEventId = 1;
     constexpr nsecs_t readTime = 3; // does not matter for this test
-    constexpr bool isDown = true;   // does not matter for this test
+    constexpr bool isDown = false;  // does not matter for this test
 
     // In the following 2 calls to trackListener, the inputEventId's are the same, but event times
     // are different.
-    mTracker->trackListener(inputEventId, isDown, /*eventTime=*/1, readTime, DEVICE_ID,
-                            {InputDeviceUsageSource::UNKNOWN});
-    mTracker->trackListener(inputEventId, isDown, /*eventTime=*/2, readTime, DEVICE_ID,
-                            {InputDeviceUsageSource::UNKNOWN});
+    mTracker->trackListener(inputEventId, /*eventTime=*/1, readTime, DEVICE_ID,
+                            {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL,
+                            InputEventType::MOTION);
+    mTracker->trackListener(inputEventId, /*eventTime=*/2, readTime, DEVICE_ID,
+                            {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL,
+                            InputEventType::MOTION);
 
     triggerEventReporting(/*eventTime=*/2);
     // Since we sent duplicate input events, the tracker should just delete all of them, because it
@@ -238,12 +246,13 @@
 TEST_F(LatencyTrackerTest, MultipleEvents_AreReportedConsistently) {
     constexpr int32_t inputEventId1 = 1;
     InputEventTimeline timeline1(
-            /*isDown*/ true,
+            /*isDown*/ false,
             /*eventTime*/ 2,
             /*readTime*/ 3,
             /*vendorId=*/0,
             /*productId=*/0,
-            /*sources=*/{InputDeviceUsageSource::UNKNOWN});
+            /*sources=*/{InputDeviceUsageSource::UNKNOWN},
+            /*inputEventType=*/InputEventActionType::UNKNOWN_INPUT_EVENT);
     timeline1.connectionTimelines.emplace(connection1,
                                           ConnectionTimeline(/*deliveryTime*/ 6, /*consumeTime*/ 7,
                                                              /*finishTime*/ 8));
@@ -260,7 +269,8 @@
             /*readTime=*/30,
             /*vendorId=*/0,
             /*productId=*/0,
-            /*sources=*/{InputDeviceUsageSource::UNKNOWN});
+            /*sources=*/{InputDeviceUsageSource::UNKNOWN},
+            /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT);
     timeline2.connectionTimelines.emplace(connection2,
                                           ConnectionTimeline(/*deliveryTime=*/60,
                                                              /*consumeTime=*/70,
@@ -272,11 +282,13 @@
     connectionTimeline2.setGraphicsTimeline(std::move(graphicsTimeline2));
 
     // Start processing first event
-    mTracker->trackListener(inputEventId1, timeline1.isDown, timeline1.eventTime,
-                            timeline1.readTime, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN});
+    mTracker->trackListener(inputEventId1, timeline1.eventTime, timeline1.readTime, DEVICE_ID,
+                            {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL,
+                            InputEventType::MOTION);
     // Start processing second event
-    mTracker->trackListener(inputEventId2, timeline2.isDown, timeline2.eventTime,
-                            timeline2.readTime, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN});
+    mTracker->trackListener(inputEventId2, timeline2.eventTime, timeline2.readTime, DEVICE_ID,
+                            {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL,
+                            InputEventType::MOTION);
     mTracker->trackFinishedEvent(inputEventId1, connection1, connectionTimeline1.deliveryTime,
                                  connectionTimeline1.consumeTime, connectionTimeline1.finishTime);
 
@@ -301,12 +313,14 @@
     const sp<IBinder>& token = timeline.connectionTimelines.begin()->first;
 
     for (size_t i = 1; i <= 100; i++) {
-        mTracker->trackListener(/*inputEventId=*/i, timeline.isDown, timeline.eventTime,
-                                timeline.readTime, /*deviceId=*/DEVICE_ID,
-                                /*sources=*/{InputDeviceUsageSource::UNKNOWN});
+        mTracker->trackListener(/*inputEventId=*/i, timeline.eventTime, timeline.readTime,
+                                /*deviceId=*/DEVICE_ID,
+                                /*sources=*/{InputDeviceUsageSource::UNKNOWN},
+                                AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION);
         expectedTimelines.push_back(InputEventTimeline{timeline.isDown, timeline.eventTime,
                                                        timeline.readTime, timeline.vendorId,
-                                                       timeline.productId, timeline.sources});
+                                                       timeline.productId, timeline.sources,
+                                                       timeline.inputEventActionType});
     }
     // Now, complete the first event that was sent.
     mTracker->trackFinishedEvent(/*inputEventId=*/1, token, expectedCT.deliveryTime,
@@ -332,12 +346,14 @@
                                  expectedCT.consumeTime, expectedCT.finishTime);
     mTracker->trackGraphicsLatency(inputEventId, connection1, expectedCT.graphicsTimeline);
 
-    mTracker->trackListener(inputEventId, expected.isDown, expected.eventTime, expected.readTime,
-                            DEVICE_ID, {InputDeviceUsageSource::UNKNOWN});
+    mTracker->trackListener(inputEventId, expected.eventTime, expected.readTime, DEVICE_ID,
+                            {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL,
+                            InputEventType::MOTION);
     triggerEventReporting(expected.eventTime);
     assertReceivedTimeline(InputEventTimeline{expected.isDown, expected.eventTime,
                                               expected.readTime, expected.vendorId,
-                                              expected.productId, expected.sources});
+                                              expected.productId, expected.sources,
+                                              expected.inputEventActionType});
 }
 
 /**
@@ -348,22 +364,92 @@
 TEST_F(LatencyTrackerTest, TrackListenerCheck_DeviceInfoFieldsInputEventTimeline) {
     constexpr int32_t inputEventId = 1;
     InputEventTimeline timeline(
-            /*isDown*/ true, /*eventTime*/ 2, /*readTime*/ 3,
+            /*isDown*/ false, /*eventTime*/ 2, /*readTime*/ 3,
             /*vendorId=*/50, /*productId=*/60,
             /*sources=*/
-            {InputDeviceUsageSource::TOUCHSCREEN, InputDeviceUsageSource::STYLUS_DIRECT});
+            {InputDeviceUsageSource::TOUCHSCREEN, InputDeviceUsageSource::STYLUS_DIRECT},
+            /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT);
     InputDeviceInfo deviceInfo1 = generateTestDeviceInfo(
             /*vendorId=*/5, /*productId=*/6, /*deviceId=*/DEVICE_ID + 1);
     InputDeviceInfo deviceInfo2 = generateTestDeviceInfo(
             /*vendorId=*/50, /*productId=*/60, /*deviceId=*/DEVICE_ID);
 
     mTracker->setInputDevices({deviceInfo1, deviceInfo2});
-    mTracker->trackListener(inputEventId, timeline.isDown, timeline.eventTime, timeline.readTime,
-                            DEVICE_ID,
+    mTracker->trackListener(inputEventId, timeline.eventTime, timeline.readTime, DEVICE_ID,
                             {InputDeviceUsageSource::TOUCHSCREEN,
-                             InputDeviceUsageSource::STYLUS_DIRECT});
+                             InputDeviceUsageSource::STYLUS_DIRECT},
+                            AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION);
     triggerEventReporting(timeline.eventTime);
     assertReceivedTimeline(timeline);
 }
 
+/**
+ * Check that InputEventActionType is correctly assigned to InputEventTimeline in trackListener.
+ */
+TEST_F(LatencyTrackerTest, TrackListenerCheck_InputEventActionTypeFieldInputEventTimeline) {
+    constexpr int32_t inputEventId = 1;
+    // Create timelines for different event types (Motion, Key)
+    InputEventTimeline motionDownTimeline(
+            /*isDown*/ true, /*eventTime*/ 2, /*readTime*/ 3,
+            /*vendorId*/ 0, /*productId*/ 0,
+            /*sources*/ {InputDeviceUsageSource::UNKNOWN},
+            /*inputEventActionType*/ InputEventActionType::MOTION_ACTION_DOWN);
+
+    InputEventTimeline motionMoveTimeline(
+            /*isDown*/ false, /*eventTime*/ 4, /*readTime*/ 5,
+            /*vendorId*/ 0, /*productId*/ 0,
+            /*sources*/ {InputDeviceUsageSource::UNKNOWN},
+            /*inputEventActionType*/ InputEventActionType::MOTION_ACTION_MOVE);
+
+    InputEventTimeline motionUpTimeline(
+            /*isDown*/ false, /*eventTime*/ 6, /*readTime*/ 7,
+            /*vendorId*/ 0, /*productId*/ 0,
+            /*sources*/ {InputDeviceUsageSource::UNKNOWN},
+            /*inputEventActionType*/ InputEventActionType::MOTION_ACTION_UP);
+
+    InputEventTimeline keyDownTimeline(
+            /*isDown*/ false, /*eventTime*/ 8, /*readTime*/ 9,
+            /*vendorId*/ 0, /*productId*/ 0,
+            /*sources*/ {InputDeviceUsageSource::UNKNOWN},
+            /*inputEventActionType*/ InputEventActionType::KEY);
+
+    InputEventTimeline keyUpTimeline(
+            /*isDown*/ false, /*eventTime*/ 10, /*readTime*/ 11,
+            /*vendorId*/ 0, /*productId*/ 0,
+            /*sources*/ {InputDeviceUsageSource::UNKNOWN},
+            /*inputEventActionType*/ InputEventActionType::KEY);
+
+    InputEventTimeline unknownTimeline(
+            /*isDown*/ false, /*eventTime*/ 12, /*readTime*/ 13,
+            /*vendorId*/ 0, /*productId*/ 0,
+            /*sources*/ {InputDeviceUsageSource::UNKNOWN},
+            /*inputEventActionType*/ InputEventActionType::UNKNOWN_INPUT_EVENT);
+
+    mTracker->trackListener(inputEventId, motionDownTimeline.eventTime, motionDownTimeline.readTime,
+                            DEVICE_ID, motionDownTimeline.sources, AMOTION_EVENT_ACTION_DOWN,
+                            InputEventType::MOTION);
+    mTracker->trackListener(inputEventId + 1, motionMoveTimeline.eventTime,
+                            motionMoveTimeline.readTime, DEVICE_ID, motionMoveTimeline.sources,
+                            AMOTION_EVENT_ACTION_MOVE, InputEventType::MOTION);
+    mTracker->trackListener(inputEventId + 2, motionUpTimeline.eventTime, motionUpTimeline.readTime,
+                            DEVICE_ID, motionUpTimeline.sources, AMOTION_EVENT_ACTION_UP,
+                            InputEventType::MOTION);
+    mTracker->trackListener(inputEventId + 3, keyDownTimeline.eventTime, keyDownTimeline.readTime,
+                            DEVICE_ID, keyDownTimeline.sources, AKEY_EVENT_ACTION_DOWN,
+                            InputEventType::KEY);
+    mTracker->trackListener(inputEventId + 4, keyUpTimeline.eventTime, keyUpTimeline.readTime,
+                            DEVICE_ID, keyUpTimeline.sources, AKEY_EVENT_ACTION_UP,
+                            InputEventType::KEY);
+    mTracker->trackListener(inputEventId + 5, unknownTimeline.eventTime, unknownTimeline.readTime,
+                            DEVICE_ID, unknownTimeline.sources, AMOTION_EVENT_ACTION_POINTER_DOWN,
+                            InputEventType::MOTION);
+
+    triggerEventReporting(unknownTimeline.eventTime);
+
+    std::vector<InputEventTimeline> expectedTimelines = {motionDownTimeline, motionMoveTimeline,
+                                                         motionUpTimeline,   keyDownTimeline,
+                                                         keyUpTimeline,      unknownTimeline};
+    assertReceivedTimelines(expectedTimelines);
+}
+
 } // namespace android::inputdispatcher
diff --git a/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
index 6daeaaf..80c2213 100644
--- a/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
@@ -18,6 +18,7 @@
 #include <linux/input.h>
 
 #include "../../InputDeviceMetricsSource.h"
+#include "../InputEventTimeline.h"
 #include "dispatcher/LatencyTracker.h"
 
 namespace android {
@@ -65,14 +66,15 @@
         fdp.PickValueInArray<std::function<void()>>({
                 [&]() -> void {
                     int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
-                    int32_t isDown = fdp.ConsumeBool();
                     nsecs_t eventTime = fdp.ConsumeIntegral<nsecs_t>();
                     nsecs_t readTime = fdp.ConsumeIntegral<nsecs_t>();
                     const DeviceId deviceId = fdp.ConsumeIntegral<int32_t>();
                     std::set<InputDeviceUsageSource> sources = {
                             fdp.ConsumeEnum<InputDeviceUsageSource>()};
-                    tracker.trackListener(inputEventId, isDown, eventTime, readTime, deviceId,
-                                          sources);
+                    int32_t inputEventActionType = fdp.ConsumeIntegral<int32_t>();
+                    const InputEventType inputEventType = fdp.ConsumeEnum<InputEventType>();
+                    tracker.trackListener(inputEventId, eventTime, readTime, deviceId, sources,
+                                          inputEventActionType, inputEventType);
                 },
                 [&]() -> void {
                     int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
index b0b1a02..eb6e677 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
@@ -33,6 +33,7 @@
 #include "DisplayHardware/HWC2.h"
 
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
+#include <aidl/android/hardware/graphics/composer3/Lut.h>
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
@@ -77,6 +78,7 @@
                  Error(const std::string&, bool, const std::vector<uint8_t>&));
     MOCK_METHOD1(setBrightness, Error(float));
     MOCK_METHOD1(setBlockingRegion, Error(const android::Region&));
+    MOCK_METHOD(Error, setLuts, (std::vector<aidl::android::hardware::graphics::composer3::Lut>&));
 };
 
 } // namespace mock
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 629d9f2..839fb7d 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -151,6 +151,10 @@
                 getOverlaySupport, (), (const, override));
     MOCK_METHOD(status_t, setRefreshRateChangedCallbackDebugEnabled, (PhysicalDisplayId, bool));
     MOCK_METHOD(status_t, notifyExpectedPresent, (PhysicalDisplayId, TimePoint, Fps));
+    MOCK_METHOD(status_t, getRequestedLuts,
+                (PhysicalDisplayId,
+                 std::vector<aidl::android::hardware::graphics::composer3::DisplayLuts::LayerLut>*),
+                (override));
 };
 
 } // namespace mock
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index 0eced73..20ae74a 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -1540,7 +1540,7 @@
     return error;
 }
 
-Error AidlComposer::getDisplayLuts(Display display, std::vector<Lut>* outLuts) {
+Error AidlComposer::getRequestedLuts(Display display, std::vector<DisplayLuts::LayerLut>* outLuts) {
     Error error = Error::NONE;
     mMutex.lock_shared();
     if (auto reader = getReader(display)) {
@@ -1552,6 +1552,18 @@
     return error;
 }
 
+Error AidlComposer::setLayerLuts(Display display, Layer layer, std::vector<Lut>& luts) {
+    Error error = Error::NONE;
+    mMutex.lock_shared();
+    if (auto writer = getWriter(display)) {
+        writer->get().setLayerLuts(translate<int64_t>(display), translate<int64_t>(layer), luts);
+    } else {
+        error = Error::BAD_DISPLAY;
+    }
+    mMutex.unlock_shared();
+    return error;
+}
+
 Error AidlComposer::setLayerBrightness(Display display, Layer layer, float brightness) {
     Error error = Error::NONE;
     mMutex.lock_shared();
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
index 3669d4c..246223a 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
@@ -244,9 +244,13 @@
     Error setRefreshRateChangedCallbackDebugEnabled(Display, bool) override;
     Error notifyExpectedPresent(Display, nsecs_t expectedPresentTime,
                                 int32_t frameIntervalNs) override;
-    Error getDisplayLuts(
+    Error getRequestedLuts(
             Display display,
-            std::vector<aidl::android::hardware::graphics::composer3::Lut>* outLuts) override;
+            std::vector<aidl::android::hardware::graphics::composer3::DisplayLuts::LayerLut>*
+                    outLuts) override;
+    Error setLayerLuts(
+            Display display, Layer layer,
+            std::vector<aidl::android::hardware::graphics::composer3::Lut>& luts) override;
 
 private:
     // Many public functions above simply write a command into the command
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 888dc08..7db9a94 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -40,6 +40,7 @@
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
 #include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
 #include <aidl/android/hardware/graphics/composer3/DisplayConfiguration.h>
+#include <aidl/android/hardware/graphics/composer3/DisplayLuts.h>
 #include <aidl/android/hardware/graphics/composer3/IComposerCallback.h>
 #include <aidl/android/hardware/graphics/composer3/Lut.h>
 #include <aidl/android/hardware/graphics/composer3/OverlayProperties.h>
@@ -304,7 +305,9 @@
     virtual Error setRefreshRateChangedCallbackDebugEnabled(Display, bool) = 0;
     virtual Error notifyExpectedPresent(Display, nsecs_t expectedPresentTime,
                                         int32_t frameIntervalNs) = 0;
-    virtual Error getDisplayLuts(Display display, std::vector<V3_0::Lut>* outLuts) = 0;
+    virtual Error getRequestedLuts(Display display,
+                                   std::vector<V3_0::DisplayLuts::LayerLut>* outLuts) = 0;
+    virtual Error setLayerLuts(Display display, Layer layer, std::vector<V3_0::Lut>& luts) = 0;
 };
 
 } // namespace Hwc2
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index d5f65c6..8e78af4 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -41,6 +41,7 @@
 using aidl::android::hardware::graphics::composer3::Composition;
 using AidlCapability = aidl::android::hardware::graphics::composer3::Capability;
 using aidl::android::hardware::graphics::composer3::DisplayCapability;
+using aidl::android::hardware::graphics::composer3::DisplayLuts;
 using aidl::android::hardware::graphics::composer3::Lut;
 using aidl::android::hardware::graphics::composer3::OverlayProperties;
 
@@ -608,13 +609,14 @@
     return static_cast<Error>(error);
 }
 
-Error Display::getDisplayLuts(std::vector<Lut>* outLuts) {
-    std::vector<Lut> tmpLuts;
-    const auto error = mComposer.getDisplayLuts(mId, &tmpLuts);
-    for (Lut& lut : tmpLuts) {
-        if (lut.pfd.get() >= 0) {
-            outLuts->push_back(
-                    {lut.layer, ndk::ScopedFileDescriptor(lut.pfd.release()), lut.lutProperties});
+Error Display::getRequestedLuts(std::vector<DisplayLuts::LayerLut>* outLayerLuts) {
+    std::vector<DisplayLuts::LayerLut> tmpLayerLuts;
+    const auto error = mComposer.getRequestedLuts(mId, &tmpLayerLuts);
+    for (DisplayLuts::LayerLut& layerLut : tmpLayerLuts) {
+        if (layerLut.lut.pfd.get() >= 0) {
+            outLayerLuts->push_back({layerLut.layer,
+                                     Lut{ndk::ScopedFileDescriptor(layerLut.lut.pfd.release()),
+                                         layerLut.lut.lutProperties}});
         }
     }
     return static_cast<Error>(error);
@@ -1050,6 +1052,14 @@
     return static_cast<Error>(intError);
 }
 
+Error Layer::setLuts(std::vector<Lut>& luts) {
+    if (CC_UNLIKELY(!mDisplay)) {
+        return Error::BAD_DISPLAY;
+    }
+    const auto intError = mComposer.setLayerLuts(mDisplay->getId(), mId, luts);
+    return static_cast<Error>(intError);
+}
+
 } // namespace impl
 } // namespace HWC2
 } // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index be2059a..c2dc943 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -179,8 +179,9 @@
     [[nodiscard]] virtual hal::Error getClientTargetProperty(
             aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness*
                     outClientTargetProperty) = 0;
-    [[nodiscard]] virtual hal::Error getDisplayLuts(
-            std::vector<aidl::android::hardware::graphics::composer3::Lut>* outLuts) = 0;
+    [[nodiscard]] virtual hal::Error getRequestedLuts(
+            std::vector<aidl::android::hardware::graphics::composer3::DisplayLuts::LayerLut>*
+                    outLuts) = 0;
     [[nodiscard]] virtual hal::Error getDisplayDecorationSupport(
             std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
                     support) = 0;
@@ -264,8 +265,9 @@
     hal::Error getClientTargetProperty(
             aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness*
                     outClientTargetProperty) override;
-    hal::Error getDisplayLuts(
-            std::vector<aidl::android::hardware::graphics::composer3::Lut>* outLuts) override;
+    hal::Error getRequestedLuts(
+            std::vector<aidl::android::hardware::graphics::composer3::DisplayLuts::LayerLut>*
+                    outLuts) override;
     hal::Error getDisplayDecorationSupport(
             std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
                     support) override;
@@ -359,6 +361,8 @@
     // AIDL HAL
     [[nodiscard]] virtual hal::Error setBrightness(float brightness) = 0;
     [[nodiscard]] virtual hal::Error setBlockingRegion(const android::Region& region) = 0;
+    [[nodiscard]] virtual hal::Error setLuts(
+            std::vector<aidl::android::hardware::graphics::composer3::Lut>& luts) = 0;
 };
 
 namespace impl {
@@ -409,6 +413,8 @@
     // AIDL HAL
     hal::Error setBrightness(float brightness) override;
     hal::Error setBlockingRegion(const android::Region& region) override;
+    hal::Error setLuts(
+            std::vector<aidl::android::hardware::graphics::composer3::Lut>& luts) override;
 
 private:
     // These are references to data owned by HWComposer, which will outlive
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 73fa855..c83e0da 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -533,6 +533,7 @@
 
     DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
     error = hwcDisplay->getClientTargetProperty(&clientTargetProperty);
+    RETURN_IF_HWC_ERROR_FOR("getClientTargetProperty", error, displayId, BAD_INDEX);
 
     outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
                                                std::move(layerRequests),
@@ -925,6 +926,21 @@
     return NO_ERROR;
 }
 
+status_t HWComposer::getRequestedLuts(
+        PhysicalDisplayId displayId,
+        std::vector<aidl::android::hardware::graphics::composer3::DisplayLuts::LayerLut>* outLuts) {
+    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+    const auto error = mDisplayData[displayId].hwcDisplay->getRequestedLuts(outLuts);
+    if (error == hal::Error::UNSUPPORTED) {
+        RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+    }
+    if (error == hal::Error::BAD_PARAMETER) {
+        RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
+    }
+    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+    return NO_ERROR;
+}
+
 status_t HWComposer::setAutoLowLatencyMode(PhysicalDisplayId displayId, bool on) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
     const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 9368b7b..dec4bfe 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -52,6 +52,7 @@
 #include <aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.h>
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
 #include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
+#include <aidl/android/hardware/graphics/composer3/DisplayLuts.h>
 #include <aidl/android/hardware/graphics/composer3/OverlayProperties.h>
 
 namespace android {
@@ -309,6 +310,11 @@
     virtual status_t setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId, bool enabled) = 0;
     virtual status_t notifyExpectedPresent(PhysicalDisplayId, TimePoint expectedPresentTime,
                                            Fps frameInterval) = 0;
+
+    // Composer 4.0
+    virtual status_t getRequestedLuts(
+            PhysicalDisplayId,
+            std::vector<aidl::android::hardware::graphics::composer3::DisplayLuts::LayerLut>*) = 0;
 };
 
 static inline bool operator==(const android::HWComposer::DeviceRequestedChanges& lhs,
@@ -472,6 +478,12 @@
     status_t notifyExpectedPresent(PhysicalDisplayId, TimePoint expectedPresentTime,
                                    Fps frameInterval) override;
 
+    // Composer 4.0
+    status_t getRequestedLuts(
+            PhysicalDisplayId,
+            std::vector<aidl::android::hardware::graphics::composer3::DisplayLuts::LayerLut>*)
+            override;
+
     // for debugging ----------------------------------------------------------
     void dump(std::string& out) const override;
     void dumpOverlayProperties(std::string& out) const override;
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
index ec2a3ec..ee1e07a 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
@@ -46,6 +46,7 @@
 using aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness;
 using aidl::android::hardware::graphics::composer3::DimmingStage;
 using aidl::android::hardware::graphics::composer3::DisplayCapability;
+using aidl::android::hardware::graphics::composer3::DisplayLuts;
 using aidl::android::hardware::graphics::composer3::Lut;
 using aidl::android::hardware::graphics::composer3::OverlayProperties;
 
@@ -1409,7 +1410,11 @@
     return Error::NONE;
 }
 
-Error HidlComposer::getDisplayLuts(Display, std::vector<Lut>*) {
+Error HidlComposer::getRequestedLuts(Display, std::vector<DisplayLuts::LayerLut>*) {
+    return Error::NONE;
+}
+
+Error HidlComposer::setLayerLuts(Display, Layer, std::vector<Lut>&) {
     return Error::NONE;
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
index 8bca5ad..701a54b 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
@@ -351,8 +351,12 @@
                                    Hdr*) override;
     Error setRefreshRateChangedCallbackDebugEnabled(Display, bool) override;
     Error notifyExpectedPresent(Display, nsecs_t, int32_t) override;
-    Error getDisplayLuts(Display,
-                         std::vector<aidl::android::hardware::graphics::composer3::Lut>*) override;
+    Error getRequestedLuts(
+            Display,
+            std::vector<aidl::android::hardware::graphics::composer3::DisplayLuts::LayerLut>*)
+            override;
+    Error setLayerLuts(Display, Layer,
+                       std::vector<aidl::android::hardware::graphics::composer3::Lut>&) override;
 
 private:
     class CommandWriter : public CommandWriterBase {
diff --git a/services/surfaceflinger/FrontEnd/Update.h b/services/surfaceflinger/FrontEnd/Update.h
index e5cca8f..4af27ab 100644
--- a/services/surfaceflinger/FrontEnd/Update.h
+++ b/services/surfaceflinger/FrontEnd/Update.h
@@ -22,28 +22,13 @@
 #include "RequestedLayerState.h"
 #include "TransactionState.h"
 
-namespace android {
-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;
-};
-} // namespace android
-
 namespace android::surfaceflinger::frontend {
 
 // Atomic set of changes affecting layer state. These changes are queued in binder threads and
 // applied every vsync.
 struct Update {
     std::vector<TransactionState> transactions;
-    std::vector<LayerCreatedState> layerCreatedStates;
+    std::vector<sp<Layer>> legacyLayers;
     std::vector<std::unique_ptr<frontend::RequestedLayerState>> newLayers;
     std::vector<LayerCreationArgs> layerCreationArgs;
     std::vector<std::pair<uint32_t, std::string /* debugName */>> destroyedHandles;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 636f7bd..7b12a80 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -231,10 +231,6 @@
     LOG_ALWAYS_FATAL_IF(std::this_thread::get_id() != mFlinger->mMainThreadId,
                         "Layer destructor called off the main thread.");
 
-    // The original layer and the clone layer share the same texture and buffer. Therefore, only
-    // one of the layers, in this case the original layer, needs to handle the deletion. The
-    // original layer and the clone should be removed at the same time so there shouldn't be any
-    // issue with the clone layer trying to use the texture.
     if (mBufferInfo.mBuffer != nullptr) {
         callReleaseBufferCallback(mDrawingState.releaseBufferListener,
                                   mBufferInfo.mBuffer->getBuffer(), mBufferInfo.mFrameNumber,
@@ -250,10 +246,6 @@
     if (mDrawingState.sidebandStream != nullptr) {
         mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
     }
-    if (mHadClonedChild) {
-        auto& roots = mFlinger->mLayerMirrorRoots;
-        roots.erase(std::remove(roots.begin(), roots.end(), this), roots.end());
-    }
     if (hasTrustedPresentationListener()) {
         mFlinger->mNumTrustedPresentationListeners--;
         updateTrustedPresentationState(nullptr, nullptr, -1 /* time_in_ms */, true /* leaveState*/);
@@ -282,48 +274,6 @@
     }
 }
 
-void Layer::removeFromCurrentState() {
-    if (!mRemovedFromDrawingState) {
-        mRemovedFromDrawingState = true;
-        mFlinger->mScheduler->deregisterLayer(this);
-    }
-    updateTrustedPresentationState(nullptr, nullptr, -1 /* time_in_ms */, true /* leaveState*/);
-
-    mFlinger->markLayerPendingRemovalLocked(sp<Layer>::fromExisting(this));
-}
-
-sp<Layer> Layer::getRootLayer() {
-    sp<Layer> parent = getParent();
-    if (parent == nullptr) {
-        return sp<Layer>::fromExisting(this);
-    }
-    return parent->getRootLayer();
-}
-
-void Layer::onRemovedFromCurrentState() {
-    // Use the root layer since we want to maintain the hierarchy for the entire subtree.
-    auto layersInTree = getRootLayer()->getLayersInTree(LayerVector::StateSet::Current);
-    std::sort(layersInTree.begin(), layersInTree.end());
-
-    REQUIRE_MUTEX(mFlinger->mStateLock);
-    traverse(LayerVector::StateSet::Current,
-             [&](Layer* layer) REQUIRES(layer->mFlinger->mStateLock) {
-                 layer->removeFromCurrentState();
-                 layer->removeRelativeZ(layersInTree);
-             });
-}
-
-void Layer::addToCurrentState() {
-    if (mRemovedFromDrawingState) {
-        mRemovedFromDrawingState = false;
-        mFlinger->mScheduler->registerLayer(this, FrameRateCompatibility::Default);
-    }
-
-    for (const auto& child : mCurrentChildren) {
-        child->addToCurrentState();
-    }
-}
-
 // ---------------------------------------------------------------------------
 // set-up
 // ---------------------------------------------------------------------------
@@ -592,7 +542,6 @@
     snapshot->alpha = alpha;
     snapshot->backgroundBlurRadius = getBackgroundBlurRadius();
     snapshot->blurRegions = getBlurRegions();
-    snapshot->stretchEffect = getStretchEffect();
 }
 
 void Layer::prepareGeometryCompositionState() {
@@ -826,33 +775,6 @@
     mTransactionFlags |= mask;
 }
 
-bool Layer::setChildLayer(const sp<Layer>& childLayer, int32_t z) {
-    ssize_t idx = mCurrentChildren.indexOf(childLayer);
-    if (idx < 0) {
-        return false;
-    }
-    if (childLayer->setLayer(z)) {
-        mCurrentChildren.removeAt(idx);
-        mCurrentChildren.add(childLayer);
-        return true;
-    }
-    return false;
-}
-
-bool Layer::setChildRelativeLayer(const sp<Layer>& childLayer,
-        const sp<IBinder>& relativeToHandle, int32_t relativeZ) {
-    ssize_t idx = mCurrentChildren.indexOf(childLayer);
-    if (idx < 0) {
-        return false;
-    }
-    if (childLayer->setRelativeLayer(relativeToHandle, relativeZ)) {
-        mCurrentChildren.removeAt(idx);
-        mCurrentChildren.add(childLayer);
-        return true;
-    }
-    return false;
-}
-
 bool Layer::setLayer(int32_t z) {
     if (mDrawingState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false;
     mDrawingState.sequence++;
@@ -959,46 +881,6 @@
     return true;
 }
 
-bool Layer::setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace) {
-    if (!mDrawingState.bgColorLayer && alpha == 0) {
-        return false;
-    }
-    mDrawingState.sequence++;
-    mDrawingState.modified = true;
-    setTransactionFlags(eTransactionNeeded);
-
-    if (!mDrawingState.bgColorLayer && alpha != 0) {
-        // create background color layer if one does not yet exist
-        uint32_t flags = ISurfaceComposerClient::eFXSurfaceEffect;
-        std::string name = mName + "BackgroundColorLayer";
-        mDrawingState.bgColorLayer = mFlinger->getFactory().createEffectLayer(
-                surfaceflinger::LayerCreationArgs(mFlinger.get(), nullptr, std::move(name), flags,
-                                                  LayerMetadata()));
-
-        // add to child list
-        addChild(mDrawingState.bgColorLayer);
-        mFlinger->mLayersAdded = true;
-        // set up SF to handle added color layer
-        if (isRemovedFromCurrentState()) {
-            MUTEX_ALIAS(mFlinger->mStateLock, mDrawingState.bgColorLayer->mFlinger->mStateLock);
-            mDrawingState.bgColorLayer->onRemovedFromCurrentState();
-        }
-        mFlinger->setTransactionFlags(eTransactionNeeded);
-    } else if (mDrawingState.bgColorLayer && alpha == 0) {
-        MUTEX_ALIAS(mFlinger->mStateLock, mDrawingState.bgColorLayer->mFlinger->mStateLock);
-        mDrawingState.bgColorLayer->reparent(nullptr);
-        mDrawingState.bgColorLayer = nullptr;
-        return true;
-    }
-
-    mDrawingState.bgColorLayer->setColor(color);
-    mDrawingState.bgColorLayer->setLayer(std::numeric_limits<int32_t>::min());
-    mDrawingState.bgColorLayer->setAlpha(alpha);
-    mDrawingState.bgColorLayer->setDataspace(dataspace);
-
-    return true;
-}
-
 bool Layer::setCornerRadius(float cornerRadius) {
     if (mDrawingState.cornerRadius == cornerRadius) return false;
 
@@ -1149,22 +1031,6 @@
     return true;
 }
 
-StretchEffect Layer::getStretchEffect() const {
-    if (mDrawingState.stretchEffect.hasEffect()) {
-        return mDrawingState.stretchEffect;
-    }
-
-    sp<Layer> parent = getParent();
-    if (parent != nullptr) {
-        auto effect = parent->getStretchEffect();
-        if (effect.hasEffect()) {
-            // TODO(b/179047472): Map it? Or do we make the effect be in global space?
-            return effect;
-        }
-    }
-    return StretchEffect{};
-}
-
 void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info,
                                                       nsecs_t postTime, gui::GameMode gameMode) {
     mDrawingState.postTime = postTime;
@@ -1439,32 +1305,6 @@
     mFlinger->mFrameTracer->onDestroy(layerId);
 }
 
-size_t Layer::getDescendantCount() const {
-    size_t count = 0;
-    for (const sp<Layer>& child : mDrawingChildren) {
-        count += 1 + child->getChildrenCount();
-    }
-    return count;
-}
-
-void Layer::addChild(const sp<Layer>& layer) {
-    mFlinger->mSomeChildrenChanged = true;
-    setTransactionFlags(eTransactionNeeded);
-
-    mCurrentChildren.add(layer);
-    layer->setParent(sp<Layer>::fromExisting(this));
-}
-
-ssize_t Layer::removeChild(const sp<Layer>& layer) {
-    mFlinger->mSomeChildrenChanged = true;
-    setTransactionFlags(eTransactionNeeded);
-
-    layer->setParent(nullptr);
-    const auto removeResult = mCurrentChildren.remove(layer);
-
-    return removeResult;
-}
-
 void Layer::setChildrenDrawingParent(const sp<Layer>& newParent) {
     for (const sp<Layer>& child : mDrawingChildren) {
         child->mDrawingParent = newParent;
@@ -1475,39 +1315,6 @@
     }
 }
 
-bool Layer::reparent(const sp<IBinder>& newParentHandle) {
-    sp<Layer> newParent;
-    if (newParentHandle != nullptr) {
-        newParent = LayerHandle::getLayer(newParentHandle);
-        if (newParent == nullptr) {
-            ALOGE("Unable to promote Layer handle");
-            return false;
-        }
-        if (newParent == this) {
-            ALOGE("Invalid attempt to reparent Layer (%s) to itself", getName().c_str());
-            return false;
-        }
-    }
-
-    sp<Layer> parent = getParent();
-    if (parent != nullptr) {
-        parent->removeChild(sp<Layer>::fromExisting(this));
-    }
-
-    if (newParentHandle != nullptr) {
-        newParent->addChild(sp<Layer>::fromExisting(this));
-        if (!newParent->isRemovedFromCurrentState()) {
-            addToCurrentState();
-        } else {
-            onRemovedFromCurrentState();
-        }
-    } else {
-        onRemovedFromCurrentState();
-    }
-
-    return true;
-}
-
 bool Layer::setColorTransform(const mat4& matrix) {
     static const mat4 identityMatrix = mat4();
 
@@ -1590,167 +1397,6 @@
     return traverse;
 }
 
-/**
- * Negatively signed relatives are before 'this' in Z-order.
- */
-void Layer::traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor) {
-    // In the case we have other layers who are using a relative Z to us, makeTraversalList will
-    // produce a new list for traversing, including our relatives, and not including our children
-    // who are relatives of another surface. In the case that there are no relative Z,
-    // makeTraversalList returns our children directly to avoid significant overhead.
-    // However in this case we need to take the responsibility for filtering children which
-    // are relatives of another surface here.
-    bool skipRelativeZUsers = false;
-    const LayerVector list = makeTraversalList(stateSet, &skipRelativeZUsers);
-
-    size_t i = 0;
-    for (; i < list.size(); i++) {
-        const auto& relative = list[i];
-        if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
-            continue;
-        }
-
-        if (relative->getZ(stateSet) >= 0) {
-            break;
-        }
-        relative->traverseInZOrder(stateSet, visitor);
-    }
-
-    visitor(this);
-    for (; i < list.size(); i++) {
-        const auto& relative = list[i];
-
-        if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
-            continue;
-        }
-        relative->traverseInZOrder(stateSet, visitor);
-    }
-}
-
-/**
- * Positively signed relatives are before 'this' in reverse Z-order.
- */
-void Layer::traverseInReverseZOrder(LayerVector::StateSet stateSet,
-                                    const LayerVector::Visitor& visitor) {
-    // See traverseInZOrder for documentation.
-    bool skipRelativeZUsers = false;
-    LayerVector list = makeTraversalList(stateSet, &skipRelativeZUsers);
-
-    int32_t i = 0;
-    for (i = int32_t(list.size()) - 1; i >= 0; i--) {
-        const auto& relative = list[i];
-
-        if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
-            continue;
-        }
-
-        if (relative->getZ(stateSet) < 0) {
-            break;
-        }
-        relative->traverseInReverseZOrder(stateSet, visitor);
-    }
-    visitor(this);
-    for (; i >= 0; i--) {
-        const auto& relative = list[i];
-
-        if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
-            continue;
-        }
-
-        relative->traverseInReverseZOrder(stateSet, visitor);
-    }
-}
-
-void Layer::traverse(LayerVector::StateSet state, const LayerVector::Visitor& visitor) {
-    visitor(this);
-    const LayerVector& children =
-          state == LayerVector::StateSet::Drawing ? mDrawingChildren : mCurrentChildren;
-    for (const sp<Layer>& child : children) {
-        child->traverse(state, visitor);
-    }
-}
-
-void Layer::traverseChildren(const LayerVector::Visitor& visitor) {
-    for (const sp<Layer>& child : mDrawingChildren) {
-        visitor(child.get());
-    }
-}
-
-LayerVector Layer::makeChildrenTraversalList(LayerVector::StateSet stateSet,
-                                             const std::vector<Layer*>& layersInTree) {
-    LOG_ALWAYS_FATAL_IF(stateSet == LayerVector::StateSet::Invalid,
-                        "makeTraversalList received invalid stateSet");
-    const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
-    const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mDrawingState : mDrawingState;
-
-    LayerVector traverse(stateSet);
-    for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
-        sp<Layer> strongRelative = weakRelative.promote();
-        // Only add relative layers that are also descendents of the top most parent of the tree.
-        // If a relative layer is not a descendent, then it should be ignored.
-        if (std::binary_search(layersInTree.begin(), layersInTree.end(), strongRelative.get())) {
-            traverse.add(strongRelative);
-        }
-    }
-
-    for (const sp<Layer>& child : children) {
-        const State& childState = useDrawing ? child->mDrawingState : child->mDrawingState;
-        // If a layer has a relativeOf layer, only ignore if the layer it's relative to is a
-        // descendent of the top most parent of the tree. If it's not a descendent, then just add
-        // the child here since it won't be added later as a relative.
-        if (std::binary_search(layersInTree.begin(), layersInTree.end(),
-                               childState.zOrderRelativeOf.promote().get())) {
-            continue;
-        }
-        traverse.add(child);
-    }
-
-    return traverse;
-}
-
-void Layer::traverseChildrenInZOrderInner(const std::vector<Layer*>& layersInTree,
-                                          LayerVector::StateSet stateSet,
-                                          const LayerVector::Visitor& visitor) {
-    const LayerVector list = makeChildrenTraversalList(stateSet, layersInTree);
-
-    size_t i = 0;
-    for (; i < list.size(); i++) {
-        const auto& relative = list[i];
-        if (relative->getZ(stateSet) >= 0) {
-            break;
-        }
-        relative->traverseChildrenInZOrderInner(layersInTree, stateSet, visitor);
-    }
-
-    visitor(this);
-    for (; i < list.size(); i++) {
-        const auto& relative = list[i];
-        relative->traverseChildrenInZOrderInner(layersInTree, stateSet, visitor);
-    }
-}
-
-std::vector<Layer*> Layer::getLayersInTree(LayerVector::StateSet stateSet) {
-    const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
-    const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-
-    std::vector<Layer*> layersInTree = {this};
-    for (size_t i = 0; i < children.size(); i++) {
-        const auto& child = children[i];
-        std::vector<Layer*> childLayers = child->getLayersInTree(stateSet);
-        layersInTree.insert(layersInTree.end(), childLayers.cbegin(), childLayers.cend());
-    }
-
-    return layersInTree;
-}
-
-void Layer::traverseChildrenInZOrder(LayerVector::StateSet stateSet,
-                                     const LayerVector::Visitor& visitor) {
-    std::vector<Layer*> layersInTree = getLayersInTree(stateSet);
-    std::sort(layersInTree.begin(), layersInTree.end());
-    traverseChildrenInZOrderInner(layersInTree, stateSet, visitor);
-}
-
 ui::Transform Layer::getTransform() const {
     return mEffectiveTransform;
 }
@@ -1861,27 +1507,6 @@
     return false;
 }
 
-void Layer::commitChildList() {
-    for (size_t i = 0; i < mCurrentChildren.size(); i++) {
-        const auto& child = mCurrentChildren[i];
-        child->commitChildList();
-    }
-    mDrawingChildren = mCurrentChildren;
-    mDrawingParent = mCurrentParent;
-    if (CC_UNLIKELY(usingRelativeZ(LayerVector::StateSet::Drawing))) {
-        auto zOrderRelativeOf = mDrawingState.zOrderRelativeOf.promote();
-        if (zOrderRelativeOf == nullptr) return;
-        if (findInHierarchy(zOrderRelativeOf)) {
-            ALOGE("Detected Z ordering loop between %s and %s", mName.c_str(),
-                  zOrderRelativeOf->mName.c_str());
-            ALOGE("Severing rel Z loop, potentially dangerous");
-            mDrawingState.isRelativeOf = false;
-            zOrderRelativeOf->removeZOrderRelative(wp<Layer>::fromExisting(this));
-        }
-    }
-}
-
-
 void Layer::setInputInfo(const WindowInfo& info) {
     mDrawingState.inputInfo = info;
     mDrawingState.touchableRegionCrop =
@@ -2048,10 +1673,6 @@
                                    [&]() { return layerInfo->mutable_destination_frame(); });
 }
 
-bool Layer::isRemovedFromCurrentState() const  {
-    return mRemovedFromDrawingState;
-}
-
 // Applies the given transform to the region, while protecting against overflows caused by any
 // offsets. If applying the offset in the transform to any of the Rects in the region would result
 // in an overflow, they are not added to the output Region.
@@ -2243,16 +1864,6 @@
         info.inputConfig |= WindowInfo::InputConfig::TRUSTED_OVERLAY;
     }
 
-    // If the layer is a clone, we need to crop the input region to cloned root to prevent
-    // touches from going outside the cloned area.
-    if (isClone()) {
-        info.inputConfig |= WindowInfo::InputConfig::CLONE;
-        if (const sp<Layer> clonedRoot = getClonedRoot()) {
-            const Rect rect = displayTransform.transform(Rect{clonedRoot->mScreenBounds});
-            info.touchableRegion = info.touchableRegion.intersect(rect);
-        }
-    }
-
     Rect bufferSize = getBufferSize(getDrawingState());
     info.contentSize = Size(bufferSize.width(), bufferSize.height());
 
@@ -2280,16 +1891,6 @@
     return Rect{layerToDisplay.transform(croppedInputBounds)};
 }
 
-sp<Layer> Layer::getClonedRoot() {
-    if (mClonedChild != nullptr) {
-        return sp<Layer>::fromExisting(this);
-    }
-    if (mDrawingParent == nullptr || mDrawingParent.promote() == nullptr) {
-        return nullptr;
-    }
-    return mDrawingParent.promote()->getClonedRoot();
-}
-
 bool Layer::hasInputInfo() const {
     return mDrawingState.inputInfo.token != nullptr ||
             mDrawingState.inputInfo.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
@@ -2329,170 +1930,6 @@
     return outputLayer ? outputLayer->getState().visibleRegion : Region();
 }
 
-void Layer::updateCloneBufferInfo() {
-    if (!isClone() || !isClonedFromAlive()) {
-        return;
-    }
-
-    sp<Layer> clonedFrom = getClonedFrom();
-    mBufferInfo = clonedFrom->mBufferInfo;
-    mSidebandStream = clonedFrom->mSidebandStream;
-    surfaceDamageRegion = clonedFrom->surfaceDamageRegion;
-    mCurrentFrameNumber = clonedFrom->mCurrentFrameNumber.load();
-    mPreviousFrameNumber = clonedFrom->mPreviousFrameNumber;
-
-    // After buffer info is updated, the drawingState from the real layer needs to be copied into
-    // the cloned. This is because some properties of drawingState can change when latchBuffer is
-    // called. However, copying the drawingState would also overwrite the cloned layer's relatives
-    // and touchableRegionCrop. Therefore, temporarily store the relatives so they can be set in
-    // the cloned drawingState again.
-    wp<Layer> tmpZOrderRelativeOf = mDrawingState.zOrderRelativeOf;
-    SortedVector<wp<Layer>> tmpZOrderRelatives = mDrawingState.zOrderRelatives;
-    wp<Layer> tmpTouchableRegionCrop = mDrawingState.touchableRegionCrop;
-    WindowInfo tmpInputInfo = mDrawingState.inputInfo;
-
-    cloneDrawingState(clonedFrom.get());
-
-    mDrawingState.touchableRegionCrop = tmpTouchableRegionCrop;
-    mDrawingState.zOrderRelativeOf = tmpZOrderRelativeOf;
-    mDrawingState.zOrderRelatives = tmpZOrderRelatives;
-    mDrawingState.inputInfo = tmpInputInfo;
-}
-
-bool Layer::updateMirrorInfo(const std::deque<Layer*>& cloneRootsPendingUpdates) {
-    if (mClonedChild == nullptr || !mClonedChild->isClonedFromAlive()) {
-        // If mClonedChild is null, there is nothing to mirror. If isClonedFromAlive returns false,
-        // it means that there is a clone, but the layer it was cloned from has been destroyed. In
-        // that case, we want to delete the reference to the clone since we want it to get
-        // destroyed. The root, this layer, will still be around since the client can continue
-        // to hold a reference, but no cloned layers will be displayed.
-        mClonedChild = nullptr;
-        return true;
-    }
-
-    std::map<sp<Layer>, sp<Layer>> clonedLayersMap;
-    // If the real layer exists and is in current state, add the clone as a child of the root.
-    // There's no need to remove from drawingState when the layer is offscreen since currentState is
-    // copied to drawingState for the root layer. So the clonedChild is always removed from
-    // drawingState and then needs to be added back each traversal.
-    if (!mClonedChild->getClonedFrom()->isRemovedFromCurrentState()) {
-        addChildToDrawing(mClonedChild);
-    }
-
-    mClonedChild->updateClonedDrawingState(clonedLayersMap);
-    mClonedChild->updateClonedChildren(sp<Layer>::fromExisting(this), clonedLayersMap);
-    mClonedChild->updateClonedRelatives(clonedLayersMap);
-
-    for (Layer* root : cloneRootsPendingUpdates) {
-        if (clonedLayersMap.find(sp<Layer>::fromExisting(root)) != clonedLayersMap.end()) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void Layer::updateClonedDrawingState(std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) {
-    // If the layer the clone was cloned from is alive, copy the content of the drawingState
-    // to the clone. If the real layer is no longer alive, continue traversing the children
-    // since we may be able to pull out other children that are still alive.
-    if (isClonedFromAlive()) {
-        sp<Layer> clonedFrom = getClonedFrom();
-        cloneDrawingState(clonedFrom.get());
-        clonedLayersMap.emplace(clonedFrom, sp<Layer>::fromExisting(this));
-    }
-
-    // The clone layer may have children in drawingState since they may have been created and
-    // added from a previous request to updateMirorInfo. This is to ensure we don't recreate clones
-    // that already exist, since we can just re-use them.
-    // The drawingChildren will not get overwritten by the currentChildren since the clones are
-    // not updated in the regular traversal. They are skipped since the root will lose the
-    // reference to them when it copies its currentChildren to drawing.
-    for (sp<Layer>& child : mDrawingChildren) {
-        child->updateClonedDrawingState(clonedLayersMap);
-    }
-}
-
-void Layer::updateClonedChildren(const sp<Layer>& mirrorRoot,
-                                 std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) {
-    mDrawingChildren.clear();
-
-    if (!isClonedFromAlive()) {
-        return;
-    }
-
-    sp<Layer> clonedFrom = getClonedFrom();
-    for (sp<Layer>& child : clonedFrom->mDrawingChildren) {
-        if (child == mirrorRoot) {
-            // This is to avoid cyclical mirroring.
-            continue;
-        }
-        sp<Layer> clonedChild = clonedLayersMap[child];
-        if (clonedChild == nullptr) {
-            clonedChild = child->createClone();
-            clonedLayersMap[child] = clonedChild;
-        }
-        addChildToDrawing(clonedChild);
-        clonedChild->updateClonedChildren(mirrorRoot, clonedLayersMap);
-    }
-}
-
-void Layer::updateClonedInputInfo(const std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) {
-    auto cropLayer = mDrawingState.touchableRegionCrop.promote();
-    if (cropLayer != nullptr) {
-        if (clonedLayersMap.count(cropLayer) == 0) {
-            // Real layer had a crop layer but it's not in the cloned hierarchy. Just set to
-            // self as crop layer to avoid going outside bounds.
-            mDrawingState.touchableRegionCrop = wp<Layer>::fromExisting(this);
-        } else {
-            const sp<Layer>& clonedCropLayer = clonedLayersMap.at(cropLayer);
-            mDrawingState.touchableRegionCrop = clonedCropLayer;
-        }
-    }
-    // Cloned layers shouldn't handle watch outside since their z order is not determined by
-    // WM or the client.
-    mDrawingState.inputInfo.setInputConfig(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH, false);
-}
-
-void Layer::updateClonedRelatives(const std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) {
-    mDrawingState.zOrderRelativeOf = wp<Layer>();
-    mDrawingState.zOrderRelatives.clear();
-
-    if (!isClonedFromAlive()) {
-        return;
-    }
-
-    const sp<Layer>& clonedFrom = getClonedFrom();
-    for (wp<Layer>& relativeWeak : clonedFrom->mDrawingState.zOrderRelatives) {
-        const sp<Layer>& relative = relativeWeak.promote();
-        if (clonedLayersMap.count(relative) > 0) {
-            auto& clonedRelative = clonedLayersMap.at(relative);
-            mDrawingState.zOrderRelatives.add(clonedRelative);
-        }
-    }
-
-    // Check if the relativeLayer for the real layer is part of the cloned hierarchy.
-    // It's possible that the layer it's relative to is outside the requested cloned hierarchy.
-    // In that case, we treat the layer as if the relativeOf has been removed. This way, it will
-    // still traverse the children, but the layer with the missing relativeOf will not be shown
-    // on screen.
-    const sp<Layer>& relativeOf = clonedFrom->mDrawingState.zOrderRelativeOf.promote();
-    if (clonedLayersMap.count(relativeOf) > 0) {
-        const sp<Layer>& clonedRelativeOf = clonedLayersMap.at(relativeOf);
-        mDrawingState.zOrderRelativeOf = clonedRelativeOf;
-    }
-
-    updateClonedInputInfo(clonedLayersMap);
-
-    for (sp<Layer>& child : mDrawingChildren) {
-        child->updateClonedRelatives(clonedLayersMap);
-    }
-}
-
-void Layer::addChildToDrawing(const sp<Layer>& layer) {
-    mDrawingChildren.add(layer);
-    layer->mDrawingParent = sp<Layer>::fromExisting(this);
-}
-
 bool Layer::isInternalDisplayOverlay() const {
     const State& s(mDrawingState);
     if (s.flags & layer_state_t::eLayerSkipScreenshot) {
@@ -2503,12 +1940,6 @@
     return parent && parent->isInternalDisplayOverlay();
 }
 
-void Layer::setClonedChild(const sp<Layer>& clonedChild) {
-    mClonedChild = clonedChild;
-    mHadClonedChild = true;
-    mFlinger->mLayerMirrorRoots.push_back(this);
-}
-
 bool Layer::setDropInputMode(gui::DropInputMode mode) {
     if (mDrawingState.dropInputMode == mode) {
         return false;
@@ -2517,15 +1948,6 @@
     return true;
 }
 
-void Layer::cloneDrawingState(const Layer* from) {
-    mDrawingState = from->mDrawingState;
-    // Skip callback info since they are not applicable for cloned layers.
-    mDrawingState.releaseBufferListener = nullptr;
-    // TODO (b/238781169) currently broken for mirror layers because we do not
-    // track release fences for mirror layers composed on other displays
-    mDrawingState.callbackHandles = {};
-}
-
 void Layer::callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
                                       const sp<GraphicBuffer>& buffer, uint64_t framenumber,
                                       const sp<Fence>& releaseFence) {
@@ -3372,13 +2794,6 @@
     }
 }
 
-sp<Layer> Layer::createClone() {
-    surfaceflinger::LayerCreationArgs args(mFlinger.get(), nullptr, mName + " (Mirror)", 0,
-                                           LayerMetadata());
-    sp<Layer> layer = mFlinger->getFactory().createBufferStateLayer(args);
-    return layer;
-}
-
 void Layer::decrementPendingBufferCount() {
     int32_t pendingBuffers = --mPendingBufferTransactions;
     tracePendingBufferCount(pendingBuffers);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f6eed63..3692fb8 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -250,8 +250,6 @@
     // true if this layer is visible, false otherwise
     virtual bool isVisible() const;
 
-    virtual sp<Layer> createClone();
-
     // Set a 2x2 transformation matrix on the layer. This transform
     // will be applied after parent transforms, but before any final
     // producer specified transform.
@@ -297,7 +295,6 @@
 
     virtual bool setMetadata(const LayerMetadata& data);
     virtual void setChildrenDrawingParent(const sp<Layer>&);
-    virtual bool reparent(const sp<IBinder>& newParentHandle) REQUIRES(mFlinger->mStateLock);
     virtual bool setColorTransform(const mat4& matrix);
     virtual mat4 getColorTransform() const;
     virtual bool hasColorTransform() const;
@@ -326,8 +323,6 @@
                            gui::GameMode gameMode);
     bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& /*handles*/,
                                           bool willPresent);
-    virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace)
-            REQUIRES(mFlinger->mStateLock);
     virtual bool setColorSpaceAgnostic(const bool agnostic);
     virtual bool setDimmingEnabled(const bool dimmingEnabled);
     virtual bool setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHint);
@@ -426,7 +421,6 @@
 
     // from graphics API
     static ui::Dataspace translateDataspace(ui::Dataspace dataspace);
-    void updateCloneBufferInfo();
     uint64_t mPreviousFrameNumber = 0;
 
     void onCompositionPresented(const DisplayDevice*,
@@ -638,8 +632,6 @@
         return {getLayerStack(), isInternalDisplayOverlay()};
     }
 
-    bool isRemovedFromCurrentState() const;
-
     perfetto::protos::LayerProto* writeToProto(perfetto::protos::LayersProto& layersProto,
                                                uint32_t traceFlags);
     void writeCompositionStateToProto(perfetto::protos::LayerProto* layerProto,
@@ -657,8 +649,6 @@
 
     gui::WindowInfo::Type getWindowType() const { return mWindowType; }
 
-    bool updateMirrorInfo(const std::deque<Layer*>& cloneRootsPendingUpdates);
-
     /*
      * doTransaction - process the transaction. This is a good place to figure
      * out which attributes of the surface have changed.
@@ -671,22 +661,6 @@
      */
     void removeRelativeZ(const std::vector<Layer*>& layersInTree);
 
-    /*
-     * Remove from current state and mark for removal.
-     */
-    void removeFromCurrentState() REQUIRES(mFlinger->mStateLock);
-
-    /*
-     * called with the state lock from a binder thread when the layer is
-     * removed from the current list to the pending removal list
-     */
-    void onRemovedFromCurrentState() REQUIRES(mFlinger->mStateLock);
-
-    /*
-     * Called when the layer is added back to the current state list.
-     */
-    void addToCurrentState();
-
     inline const State& getDrawingState() const { return mDrawingState; }
     inline State& getDrawingState() { return mDrawingState; }
 
@@ -715,57 +689,9 @@
     // is ready to acquire a buffer.
     ui::Transform::RotationFlags getFixedTransformHint() const;
 
-    /**
-     * Traverse this layer and it's hierarchy of children directly. Unlike traverseInZOrder
-     * which will not emit children who have relativeZOrder to another layer, this method
-     * just directly emits all children. It also emits them in no particular order.
-     * So this method is not suitable for graphical operations, as it doesn't represent
-     * the scene state, but it's also more efficient than traverseInZOrder and so useful for
-     * book-keeping.
-     */
-    void traverse(LayerVector::StateSet, const LayerVector::Visitor&);
-    void traverseInReverseZOrder(LayerVector::StateSet, const LayerVector::Visitor&);
-    void traverseInZOrder(LayerVector::StateSet, const LayerVector::Visitor&);
-    void traverseChildren(const LayerVector::Visitor&);
-
-    /**
-     * Traverse only children in z order, ignoring relative layers that are not children of the
-     * parent.
-     */
-    void traverseChildrenInZOrder(LayerVector::StateSet, const LayerVector::Visitor&);
-
-    size_t getDescendantCount() const;
-    size_t getChildrenCount() const { return mDrawingChildren.size(); }
     bool isHandleAlive() const { return mHandleAlive; }
     bool onHandleDestroyed() { return mHandleAlive = false; }
-
-    // ONLY CALL THIS FROM THE LAYER DTOR!
-    // See b/141111965.  We need to add current children to offscreen layers in
-    // the layer dtor so as not to dangle layers.  Since the layer has not
-    // committed its transaction when the layer is destroyed, we must add
-    // current children.  This is safe in the dtor as we will no longer update
-    // the current state, but should not be called anywhere else!
-    LayerVector& getCurrentChildren() { return mCurrentChildren; }
-
-    void addChild(const sp<Layer>&);
-    // Returns index if removed, or negative value otherwise
-    // for symmetry with Vector::remove
-    ssize_t removeChild(const sp<Layer>& layer);
-    sp<Layer> getParent() const { return mCurrentParent.promote(); }
-
-    // Should be called with the surfaceflinger statelock held
-    bool isAtRoot() const { return mIsAtRoot; }
-    void setIsAtRoot(bool isAtRoot) { mIsAtRoot = isAtRoot; }
-
-    bool hasParent() const { return getParent() != nullptr; }
     Rect getScreenBounds(bool reduceTransparentRegion = true) const;
-    bool setChildLayer(const sp<Layer>& childLayer, int32_t z);
-    bool setChildRelativeLayer(const sp<Layer>& childLayer,
-            const sp<IBinder>& relativeToHandle, int32_t relativeZ);
-
-    // Copy the current list of children to the drawing state. Called by
-    // SurfaceFlinger to complete a transaction.
-    void commitChildList();
     int32_t getZ(LayerVector::StateSet) const;
 
     /**
@@ -823,15 +749,6 @@
 
     int32_t getOwnerAppId() { return mOwnerAppId; }
 
-    // This layer is not a clone, but it's the parent to the cloned hierarchy. The
-    // variable mClonedChild represents the top layer that will be cloned so this
-    // layer will be the parent of mClonedChild.
-    // The layers in the cloned hierarchy will match the lifetime of the real layers. That is
-    // if the real layer is destroyed, then the clone layer will also be destroyed.
-    sp<Layer> mClonedChild;
-    bool mHadClonedChild = false;
-    void setClonedChild(const sp<Layer>& mClonedChild);
-
     mutable bool contentDirty{false};
     Region surfaceDamageRegion;
 
@@ -855,7 +772,6 @@
     }
 
     bool setStretchEffect(const StretchEffect& effect);
-    StretchEffect getStretchEffect() const;
 
     bool setBufferCrop(const Rect& /* bufferCrop */);
     bool setDestinationFrame(const Rect& /* destinationFrame */);
@@ -877,10 +793,6 @@
     // CompositionEngine to create a single path for composing layers.
     void updateSnapshot(bool updateGeometry);
     void updateChildrenSnapshots(bool updateGeometry);
-    sp<Layer> getClonedFrom() const {
-        return mClonedFrom != nullptr ? mClonedFrom.promote() : nullptr;
-    }
-    bool isClone() { return mClonedFrom != nullptr; }
 
     bool willPresentCurrentTransaction() const;
 
@@ -946,16 +858,6 @@
     void preparePerFrameEffectsCompositionState();
     void gatherBufferInfo();
 
-    bool isClonedFromAlive() { return getClonedFrom() != nullptr; }
-
-    void cloneDrawingState(const Layer* from);
-    void updateClonedDrawingState(std::map<sp<Layer>, sp<Layer>>& clonedLayersMap);
-    void updateClonedChildren(const sp<Layer>& mirrorRoot,
-                              std::map<sp<Layer>, sp<Layer>>& clonedLayersMap);
-    void updateClonedRelatives(const std::map<sp<Layer>, sp<Layer>>& clonedLayersMap);
-    void addChildToDrawing(const sp<Layer>&);
-    void updateClonedInputInfo(const std::map<sp<Layer>, sp<Layer>>& clonedLayersMap);
-
     void prepareBasicGeometryCompositionState();
     void prepareGeometryCompositionState();
     void prepareCursorCompositionState();
@@ -1086,19 +988,6 @@
             const DisplayDevice&) const;
     aidl::android::hardware::graphics::composer3::Composition getCompositionType(
             const compositionengine::OutputLayer*) const;
-    /**
-     * Returns an unsorted vector of all layers that are part of this tree.
-     * That includes the current layer and all its descendants.
-     */
-    std::vector<Layer*> getLayersInTree(LayerVector::StateSet);
-    /**
-     * Traverses layers that are part of this tree in the correct z order.
-     * layersInTree must be sorted before calling this method.
-     */
-    void traverseChildrenInZOrderInner(const std::vector<Layer*>& layersInTree,
-                                       LayerVector::StateSet, const LayerVector::Visitor&);
-    LayerVector makeChildrenTraversalList(LayerVector::StateSet,
-                                          const std::vector<Layer*>& layersInTree);
 
     bool propagateFrameRateForLayerTree(FrameRate parentFrameRate, bool overrideChildren,
                                         bool* transactionNeeded);
@@ -1107,10 +996,6 @@
     gui::DropInputMode getDropInputMode() const;
     void handleDropInputMode(gui::WindowInfo& info) const;
 
-    // Find the root of the cloned hierarchy, this means the first non cloned parent.
-    // This will return null if first non cloned parent is not found.
-    sp<Layer> getClonedRoot();
-
     // Finds the top most layer in the hierarchy. This will find the root Layer where the parent is
     // null.
     sp<Layer> getRootLayer();
@@ -1185,12 +1070,6 @@
 
     bool mGetHandleCalled = false;
 
-    // The current layer is a clone of mClonedFrom. This means that this layer will update it's
-    // properties based on mClonedFrom. When mClonedFrom latches a new buffer for BufferLayers,
-    // this layer will update it's buffer. When mClonedFrom updates it's drawing state, children,
-    // and relatives, this layer will update as well.
-    wp<Layer> mClonedFrom;
-
     // The inherited shadow radius after taking into account the layer hierarchy. This is the
     // final shadow radius for this layer. If a shadow is specified for a layer, then effective
     // shadow radius is the set shadow radius, otherwise its the parent's shadow radius.
diff --git a/services/surfaceflinger/LayerVector.cpp b/services/surfaceflinger/LayerVector.cpp
index f52e60d..ff0a955 100644
--- a/services/surfaceflinger/LayerVector.cpp
+++ b/services/surfaceflinger/LayerVector.cpp
@@ -61,35 +61,6 @@
     return (l->sequence > r->sequence) ? 1 : -1;
 }
 
-void LayerVector::traverseInZOrder(StateSet stateSet, const Visitor& visitor) const {
-    for (size_t i = 0; i < size(); i++) {
-        const auto& layer = (*this)[i];
-        auto& state = layer->getDrawingState();
-        if (state.isRelativeOf) {
-            continue;
-        }
-        layer->traverseInZOrder(stateSet, visitor);
-    }
-}
-
-void LayerVector::traverseInReverseZOrder(StateSet stateSet, const Visitor& visitor) const {
-    for (auto i = static_cast<int64_t>(size()) - 1; i >= 0; i--) {
-        const auto& layer = (*this)[i];
-        auto& state = layer->getDrawingState();
-        if (state.isRelativeOf) {
-            continue;
-        }
-        layer->traverseInReverseZOrder(stateSet, visitor);
-     }
-}
-
-void LayerVector::traverse(const Visitor& visitor) const {
-    for (auto i = static_cast<int64_t>(size()) - 1; i >= 0; i--) {
-        const auto& layer = (*this)[i];
-        layer->traverse(mStateSet, visitor);
-    }
-}
-
 } // namespace android
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/LayerVector.h b/services/surfaceflinger/LayerVector.h
index a531f4f..38dc11d 100644
--- a/services/surfaceflinger/LayerVector.h
+++ b/services/surfaceflinger/LayerVector.h
@@ -46,11 +46,8 @@
 
     // Sorts layer by layer-stack, Z order, and finally creation order (sequence).
     int do_compare(const void* lhs, const void* rhs) const override;
-
     using Visitor = std::function<void(Layer*)>;
-    void traverseInReverseZOrder(StateSet stateSet, const Visitor& visitor) const;
-    void traverseInZOrder(StateSet stateSet, const Visitor& visitor) const;
-    void traverse(const Visitor& visitor) const;
+
 private:
     const StateSet mStateSet;
 };
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a232228..ce83475 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2371,7 +2371,7 @@
         {
             // TODO(b/238781169) lockless queue this and keep order.
             std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
-            update.layerCreatedStates = std::move(mCreatedLayers);
+            update.legacyLayers = std::move(mCreatedLayers);
             mCreatedLayers.clear();
             update.newLayers = std::move(mNewLayers);
             mNewLayers.clear();
@@ -2390,11 +2390,8 @@
         }
         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;
-            }
+        for (auto& legacyLayer : update.legacyLayers) {
+            mLegacyLayers[legacyLayer->sequence] = legacyLayer;
         }
         mLayerHierarchyBuilder.update(mLayerLifecycleManager);
     }
@@ -2848,9 +2845,7 @@
         for (auto [layer, layerFE] : layers) {
             CompositionResult compositionResult{layerFE->stealCompositionResult()};
             for (auto& [releaseFence, layerStack] : compositionResult.releaseFences) {
-                Layer* clonedFrom = layer->getClonedFrom().get();
-                auto owningLayer = clonedFrom ? clonedFrom : layer;
-                owningLayer->onLayerDisplayed(std::move(releaseFence), layerStack);
+                layer->onLayerDisplayed(std::move(releaseFence), layerStack);
             }
             if (compositionResult.lastClientCompositionFence) {
                 layer->setWasClientComposed(compositionResult.lastClientCompositionFence);
@@ -4336,55 +4331,8 @@
 
 void SurfaceFlinger::doCommitTransactions() {
     SFTRACE_CALL();
-
-    if (!mLayersPendingRemoval.isEmpty()) {
-        // Notify removed layers now that they can't be drawn from
-        for (const auto& l : mLayersPendingRemoval) {
-            // Ensure any buffers set to display on any children are released.
-            if (l->isRemovedFromCurrentState()) {
-                l->latchAndReleaseBuffer();
-            }
-
-            // If a layer has a parent, we allow it to out-live it's handle
-            // with the idea that the parent holds a reference and will eventually
-            // be cleaned up. However no one cleans up the top-level so we do so
-            // here.
-            if (l->isAtRoot()) {
-                l->setIsAtRoot(false);
-                mCurrentState.layersSortedByZ.remove(l);
-            }
-        }
-        mLayersPendingRemoval.clear();
-    }
-
     mDrawingState = mCurrentState;
     mCurrentState.colorMatrixChanged = false;
-
-    if (mVisibleRegionsDirty) {
-        for (const auto& rootLayer : mDrawingState.layersSortedByZ) {
-            rootLayer->commitChildList();
-        }
-    }
-
-    if (mLayerMirrorRoots.size() > 0) {
-        std::deque<Layer*> pendingUpdates;
-        pendingUpdates.insert(pendingUpdates.end(), mLayerMirrorRoots.begin(),
-                              mLayerMirrorRoots.end());
-        std::vector<Layer*> needsUpdating;
-        for (Layer* cloneRoot : mLayerMirrorRoots) {
-            pendingUpdates.pop_front();
-            if (cloneRoot->isRemovedFromCurrentState()) {
-                continue;
-            }
-            if (cloneRoot->updateMirrorInfo(pendingUpdates)) {
-            } else {
-                needsUpdating.push_back(cloneRoot);
-            }
-        }
-        for (Layer* cloneRoot : needsUpdating) {
-            cloneRoot->updateMirrorInfo({});
-        }
-    }
 }
 
 void SurfaceFlinger::invalidateLayerStack(const ui::LayerFilter& layerFilter, const Region& dirty) {
@@ -4427,7 +4375,7 @@
     args.layerIdToMirror = LayerHandle::getLayerId(args.mirrorLayerHandle.promote());
     {
         std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
-        mCreatedLayers.emplace_back(layer, parent, args.addToRoot);
+        mCreatedLayers.emplace_back(layer);
         mNewLayers.emplace_back(std::make_unique<frontend::RequestedLayerState>(args));
         args.mirrorLayerHandle.clear();
         args.parentHandle.clear();
@@ -5153,8 +5101,6 @@
         if (result != NO_ERROR) {
             return result;
         }
-
-        mirrorLayer->setClonedChild(mirrorFrom->createClone());
     }
 
     outResult.layerId = mirrorLayer->sequence;
@@ -5268,33 +5214,22 @@
     return NO_ERROR;
 }
 
-void SurfaceFlinger::markLayerPendingRemovalLocked(const sp<Layer>& layer) {
-    mLayersPendingRemoval.add(layer);
-    mLayersRemoved = true;
-    setTransactionFlags(eTransactionNeeded);
-}
-
 void SurfaceFlinger::onHandleDestroyed(BBinder* handle, sp<Layer>& layer, uint32_t layerId) {
     {
-        std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
-        mDestroyedHandles.emplace_back(layerId, layer->getDebugName());
-    }
-
-    {
         // Used to remove stalled transactions which uses an internal lock.
         ftl::FakeGuard guard(kMainThreadContext);
         mTransactionHandler.onLayerDestroyed(layerId);
     }
-
     JankTracker::flushJankData(layerId);
 
-    Mutex::Autolock lock(mStateLock);
-    markLayerPendingRemovalLocked(layer);
+    std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
+    mDestroyedHandles.emplace_back(layerId, layer->getDebugName());
+
+    Mutex::Autolock stateLock(mStateLock);
     layer->onHandleDestroyed();
     mBufferCountTracker.remove(handle);
     layer.clear();
-
-    setTransactionFlags(eTransactionFlushNeeded);
+    setTransactionFlags(eTransactionFlushNeeded | eTransactionNeeded);
 }
 
 void SurfaceFlinger::initializeDisplays() {
@@ -7199,9 +7134,7 @@
 void SurfaceFlinger::attachReleaseFenceFutureToLayer(Layer* layer, LayerFE* layerFE,
                                                      ui::LayerStack layerStack) {
     ftl::Future<FenceResult> futureFence = layerFE->createReleaseFenceFuture();
-    Layer* clonedFrom = layer->getClonedFrom().get();
-    auto owningLayer = clonedFrom ? clonedFrom : layer;
-    owningLayer->prepareReleaseCallbacks(std::move(futureFence), layerStack);
+    layer->prepareReleaseCallbacks(std::move(futureFence), layerStack);
 }
 
 // Loop over all visible layers to see whether there's any protected layer. A protected layer is
@@ -7669,18 +7602,6 @@
 
 // ---------------------------------------------------------------------------
 
-void SurfaceFlinger::State::traverse(const LayerVector::Visitor& visitor) const {
-    layersSortedByZ.traverse(visitor);
-}
-
-void SurfaceFlinger::State::traverseInZOrder(const LayerVector::Visitor& visitor) const {
-    layersSortedByZ.traverseInZOrder(stateSet, visitor);
-}
-
-void SurfaceFlinger::State::traverseInReverseZOrder(const LayerVector::Visitor& visitor) const {
-    layersSortedByZ.traverseInReverseZOrder(stateSet, visitor);
-}
-
 ftl::Optional<scheduler::FrameRateMode> SurfaceFlinger::getPreferredDisplayMode(
         PhysicalDisplayId displayId, DisplayModeId defaultModeId) const {
     if (const auto schedulerMode = mScheduler->getPreferredDisplayMode();
@@ -7849,16 +7770,12 @@
 
 void SurfaceFlinger::onLayerFirstRef(Layer* layer) {
     mNumLayers++;
-    if (!layer->isRemovedFromCurrentState()) {
-        mScheduler->registerLayer(layer, scheduler::FrameRateCompatibility::Default);
-    }
+    mScheduler->registerLayer(layer, scheduler::FrameRateCompatibility::Default);
 }
 
 void SurfaceFlinger::onLayerDestroyed(Layer* layer) {
     mNumLayers--;
-    if (!layer->isRemovedFromCurrentState()) {
-        mScheduler->deregisterLayer(layer);
-    }
+    mScheduler->deregisterLayer(layer);
     if (mTransactionTracing) {
         mTransactionTracing->onLayerRemoved(layer->getSequence());
     }
@@ -8011,37 +7928,6 @@
     return calculateMaxAcquiredBufferCount(refreshRate, presentLatency);
 }
 
-void SurfaceFlinger::handleLayerCreatedLocked(const LayerCreatedState& state, VsyncId vsyncId) {
-    sp<Layer> layer = state.layer.promote();
-    if (!layer) {
-        ALOGD("Layer was destroyed soon after creation %p", state.layer.unsafe_get());
-        return;
-    }
-    MUTEX_ALIAS(mStateLock, layer->mFlinger->mStateLock);
-
-    sp<Layer> parent;
-    bool addToRoot = state.addToRoot;
-    if (state.initialParent != nullptr) {
-        parent = state.initialParent.promote();
-        if (parent == nullptr) {
-            ALOGD("Parent was destroyed soon after creation %p", state.initialParent.unsafe_get());
-            addToRoot = false;
-        }
-    }
-
-    if (parent == nullptr && addToRoot) {
-        layer->setIsAtRoot(true);
-        mCurrentState.layersSortedByZ.add(layer);
-    } else if (parent == nullptr) {
-        layer->onRemovedFromCurrentState();
-    } else if (parent->isRemovedFromCurrentState()) {
-        parent->addChild(layer);
-        layer->onRemovedFromCurrentState();
-    } else {
-        parent->addChild(layer);
-    }
-}
-
 void SurfaceFlinger::sample() {
     if (!mLumaSampling || !mRegionSamplingThread) {
         return;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 873fac2..414088e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -297,8 +297,6 @@
     // the client can no longer modify this layer directly.
     void onHandleDestroyed(BBinder* handle, sp<Layer>& layer, uint32_t layerId);
 
-    std::vector<Layer*> mLayerMirrorRoots;
-
     TransactionCallbackInvoker& getTransactionCallbackInvoker() {
         return mTransactionCallbackInvoker;
     }
@@ -389,11 +387,10 @@
 
     class State {
     public:
-        explicit State(LayerVector::StateSet set) : stateSet(set), layersSortedByZ(set) {}
+        explicit State(LayerVector::StateSet set) : stateSet(set) {}
         State& operator=(const State& other) {
             // We explicitly don't copy stateSet so that, e.g., mDrawingState
             // always uses the Drawing StateSet.
-            layersSortedByZ = other.layersSortedByZ;
             displays = other.displays;
             colorMatrixChanged = other.colorMatrixChanged;
             if (colorMatrixChanged) {
@@ -405,7 +402,6 @@
         }
 
         const LayerVector::StateSet stateSet = LayerVector::StateSet::Invalid;
-        LayerVector layersSortedByZ;
 
         // TODO(b/241285876): Replace deprecated DefaultKeyedVector with ftl::SmallMap.
         DefaultKeyedVector<wp<IBinder>, DisplayDeviceState> displays;
@@ -425,10 +421,6 @@
         mat4 colorMatrix;
 
         ShadowSettings globalShadowSettings;
-
-        void traverse(const LayerVector::Visitor& visitor) const;
-        void traverseInZOrder(const LayerVector::Visitor& visitor) const;
-        void traverseInReverseZOrder(const LayerVector::Visitor& visitor) const;
     };
 
     // Keeps track of pending buffers per layer handle in the transaction queue or current/drawing
@@ -847,8 +839,6 @@
     status_t mirrorDisplay(DisplayId displayId, const LayerCreationArgs& args,
                            gui::CreateSurfaceResult& outResult);
 
-    void markLayerPendingRemovalLocked(const sp<Layer>& layer) REQUIRES(mStateLock);
-
     // add a layer to SurfaceFlinger
     status_t addClientLayer(LayerCreationArgs& args, const sp<IBinder>& handle,
                             const sp<Layer>& layer, const wp<Layer>& parentLayer,
@@ -1199,7 +1189,6 @@
     State mCurrentState{LayerVector::StateSet::Current};
     std::atomic<int32_t> mTransactionFlags = 0;
     std::atomic<uint32_t> mUniqueTransactionId = 1;
-    SortedVector<sp<Layer>> mLayersPendingRemoval;
 
     // Buffers that have been discarded by clients and need to be evicted from per-layer caches so
     // the graphics memory can be immediately freed.
@@ -1389,13 +1378,6 @@
     std::unordered_map<DisplayId, sp<HdrLayerInfoReporter>> mHdrLayerInfoListeners
             GUARDED_BY(mStateLock);
 
-    mutable std::mutex mCreatedLayersLock;
-
-    // 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);
-    void handleLayerCreatedLocked(const LayerCreatedState&, VsyncId) REQUIRES(mStateLock);
-
     std::atomic<ui::Transform::RotationFlags> mActiveDisplayTransformHint;
 
     // Must only be accessed on the main thread.
@@ -1436,6 +1418,8 @@
     frontend::LayerHierarchyBuilder mLayerHierarchyBuilder GUARDED_BY(kMainThreadContext);
     frontend::LayerSnapshotBuilder mLayerSnapshotBuilder GUARDED_BY(kMainThreadContext);
 
+    mutable std::mutex mCreatedLayersLock;
+    std::vector<sp<Layer>> mCreatedLayers GUARDED_BY(mCreatedLayersLock);
     std::vector<std::pair<uint32_t, std::string>> mDestroyedHandles GUARDED_BY(mCreatedLayersLock);
     std::vector<std::unique_ptr<frontend::RequestedLayerState>> mNewLayers
             GUARDED_BY(mCreatedLayersLock);
diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp
index 07c720f..8ec908f 100644
--- a/services/surfaceflinger/common/FlagManager.cpp
+++ b/services/surfaceflinger/common/FlagManager.cpp
@@ -155,6 +155,7 @@
     DUMP_READ_ONLY_FLAG(force_compile_graphite_renderengine);
     DUMP_READ_ONLY_FLAG(single_hop_screenshot);
     DUMP_READ_ONLY_FLAG(trace_frame_rate_override);
+    DUMP_READ_ONLY_FLAG(true_hdr_screenshots);
 
 #undef DUMP_READ_ONLY_FLAG
 #undef DUMP_SERVER_FLAG
@@ -259,6 +260,7 @@
 FLAG_MANAGER_READ_ONLY_FLAG(flush_buffer_slots_to_uncache, "");
 FLAG_MANAGER_READ_ONLY_FLAG(force_compile_graphite_renderengine, "");
 FLAG_MANAGER_READ_ONLY_FLAG(single_hop_screenshot, "");
+FLAG_MANAGER_READ_ONLY_FLAG(true_hdr_screenshots, "debug.sf.true_hdr_screenshots");
 
 /// Trunk stable server flags ///
 FLAG_MANAGER_SERVER_FLAG(refresh_rate_overlay_on_external_display, "")
diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h
index a4b4a2b..473e564 100644
--- a/services/surfaceflinger/common/include/common/FlagManager.h
+++ b/services/surfaceflinger/common/include/common/FlagManager.h
@@ -93,6 +93,7 @@
     bool force_compile_graphite_renderengine() const;
     bool single_hop_screenshot() const;
     bool trace_frame_rate_override() const;
+    bool true_hdr_screenshots() const;
 
 protected:
     // overridden for unit tests
diff --git a/services/surfaceflinger/surfaceflinger_flags_new.aconfig b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
index 886167e..0ff846e7 100644
--- a/services/surfaceflinger/surfaceflinger_flags_new.aconfig
+++ b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
@@ -114,6 +114,14 @@
   }
  } # single_hop_screenshot
 
+flag {
+    name: "true_hdr_screenshots"
+    namespace: "core_graphics"
+    description: "Enables screenshotting display content in HDR, sans tone mapping"
+    bug: "329470026"
+    is_fixed_read_only: true
+} # true_hdr_screenshots
+
  flag {
   name: "override_trusted_overlay"
   namespace: "window_surfaces"
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 358f6b0..45ca7e2 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -884,7 +884,6 @@
             mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
 
     layer.clear();
-    mFlinger.mutableLayersPendingRemoval().clear();
     EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
 }
 
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index a6a2758..710b5cc 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -721,7 +721,6 @@
     }
 
     auto& mutableMinAcquiredBuffers() { return SurfaceFlinger::minAcquiredBuffers; }
-    auto& mutableLayersPendingRemoval() { return mFlinger->mLayersPendingRemoval; }
     auto& mutableLayerSnapshotBuilder() { return mFlinger->mLayerSnapshotBuilder; };
 
     auto fromHandle(const sp<IBinder>& handle) { return LayerHandle::getLayer(handle); }
@@ -789,7 +788,6 @@
         mutableDisplays().clear();
         mutableCurrentState().displays.clear();
         mutableDrawingState().displays.clear();
-        mFlinger->mLayersPendingRemoval.clear();
         mFlinger->mScheduler.reset();
         mFlinger->mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>());
         mFlinger->mRenderEngine = std::unique_ptr<renderengine::RenderEngine>();
diff --git a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
index 7bf1674..f8f08c7 100644
--- a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
@@ -20,6 +20,7 @@
 #include <gui/SurfaceComposerClient.h>
 #include <cstdint>
 #include "Client.h"
+#include "Layer.h"
 
 #include <layerproto/LayerProtoHeader.h>
 #include "FrontEnd/LayerCreationArgs.h"
diff --git a/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
index 9f6065b..e27af0e 100644
--- a/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
@@ -128,12 +128,10 @@
             NativeHandle::create(reinterpret_cast<native_handle_t*>(DEFAULT_SIDEBAND_STREAM),
                                  false);
     layer->setSidebandStream(stream, FrameTimelineInfo{}, 20, gui::GameMode::Unsupported);
-    mFlinger.mutableCurrentState().layersSortedByZ.add(layer);
     mTunnelModeEnabledReporter->updateTunnelModeStatus();
     mTunnelModeEnabledReporter->addListener(mTunnelModeEnabledListener);
     EXPECT_EQ(true, mTunnelModeEnabledListener->mTunnelModeEnabled);
     mTunnelModeEnabledReporter->removeListener(mTunnelModeEnabledListener);
-    mFlinger.mutableCurrentState().layersSortedByZ.remove(layer);
     layer = nullptr;
 
     mTunnelModeEnabledReporter->updateTunnelModeStatus();
@@ -154,12 +152,9 @@
     layerWithSidebandStream->setSidebandStream(stream, FrameTimelineInfo{}, 20,
                                                gui::GameMode::Unsupported);
 
-    mFlinger.mutableCurrentState().layersSortedByZ.add(simpleLayer);
-    mFlinger.mutableCurrentState().layersSortedByZ.add(layerWithSidebandStream);
     mTunnelModeEnabledReporter->updateTunnelModeStatus();
     EXPECT_EQ(true, mTunnelModeEnabledListener->mTunnelModeEnabled);
 
-    mFlinger.mutableCurrentState().layersSortedByZ.remove(layerWithSidebandStream);
     layerWithSidebandStream = nullptr;
     mTunnelModeEnabledReporter->updateTunnelModeStatus();
     EXPECT_EQ(false, mTunnelModeEnabledListener->mTunnelModeEnabled);
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index e380e19..f472d8f 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -180,8 +180,12 @@
     MOCK_METHOD1(onHotplugDisconnect, void(Display));
     MOCK_METHOD(Error, setRefreshRateChangedCallbackDebugEnabled, (Display, bool));
     MOCK_METHOD(Error, notifyExpectedPresent, (Display, nsecs_t, int32_t));
-    MOCK_METHOD(Error, getDisplayLuts,
-                (Display, std::vector<aidl::android::hardware::graphics::composer3::Lut>*));
+    MOCK_METHOD(
+            Error, getRequestedLuts,
+            (Display,
+             std::vector<aidl::android::hardware::graphics::composer3::DisplayLuts::LayerLut>*));
+    MOCK_METHOD(Error, setLayerLuts,
+                (Display, Layer, std::vector<aidl::android::hardware::graphics::composer3::Lut>&));
 };
 
 } // namespace Hwc2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
index 1eda358..2cc1987 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
@@ -109,8 +109,9 @@
     MOCK_METHOD(hal::Error, getOverlaySupport,
                 (aidl::android::hardware::graphics::composer3::OverlayProperties *),
                 (const override));
-    MOCK_METHOD(hal::Error, getDisplayLuts,
-                (std::vector<aidl::android::hardware::graphics::composer3::Lut>*), (override));
+    MOCK_METHOD(hal::Error, getRequestedLuts,
+                (std::vector<aidl::android::hardware::graphics::composer3::DisplayLuts::LayerLut>*),
+                (override));
 };
 
 class Layer : public HWC2::Layer {
@@ -145,6 +146,8 @@
                 (const std::string &, bool, const std::vector<uint8_t> &), (override));
     MOCK_METHOD(hal::Error, setBrightness, (float), (override));
     MOCK_METHOD(hal::Error, setBlockingRegion, (const android::Region &), (override));
+    MOCK_METHOD(hal::Error, setLuts,
+                (std::vector<aidl::android::hardware::graphics::composer3::Lut>&), (override));
 };
 
 } // namespace android::HWC2::mock