Merge "Allow latch unsignaled if there are no flag changes" into main
diff --git a/cmds/dumpstate/DumpstateUtil.h b/cmds/dumpstate/DumpstateUtil.h
index 9e955e3..ae7152a 100644
--- a/cmds/dumpstate/DumpstateUtil.h
+++ b/cmds/dumpstate/DumpstateUtil.h
@@ -18,6 +18,7 @@
 
 #include <cstdint>
 #include <string>
+#include <vector>
 
 /*
  * Converts seconds to milliseconds.
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 39573ec..fbcf823 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -20,6 +20,7 @@
 
 #include <inttypes.h>
 #include <unistd.h>
+#include <condition_variable>
 
 #include <android-base/properties.h>
 #include <android/os/BnServiceCallback.h>
@@ -642,7 +643,7 @@
 
 protected:
     // Override realGetService for ServiceManagerShim::waitForService.
-    Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
+    Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) override {
         *_aidl_return = getDeviceService({"-g", name}, mOptions);
         return Status::ok();
     }
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 611169d..3f70e8c 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -2768,7 +2768,7 @@
         }
         if (type == BINDER_TYPE_FD) {
             // FDs from the kernel are always owned
-            FdTag(flat->handle, 0, this);
+            FdTag(flat->handle, nullptr, this);
         }
         minOffset = offset + sizeof(flat_binder_object);
     }
diff --git a/libs/binder/RecordedTransaction.cpp b/libs/binder/RecordedTransaction.cpp
index de2a69f..924537e 100644
--- a/libs/binder/RecordedTransaction.cpp
+++ b/libs/binder/RecordedTransaction.cpp
@@ -230,8 +230,8 @@
         }
 
         size_t memoryMappedSize = chunkPayloadSize + mmapPayloadStartOffset;
-        void* mappedMemory =
-                mmap(NULL, memoryMappedSize, PROT_READ, MAP_SHARED, fd.get(), mmapPageAlignedStart);
+        void* mappedMemory = mmap(nullptr, memoryMappedSize, PROT_READ, MAP_SHARED, fd.get(),
+                                  mmapPageAlignedStart);
         auto mmap_guard = make_scope_guard(
                 [mappedMemory, memoryMappedSize] { munmap(mappedMemory, memoryMappedSize); });
 
@@ -382,7 +382,7 @@
         return UNKNOWN_ERROR;
     }
 
-    if (NO_ERROR != writeChunk(fd, END_CHUNK, 0, NULL)) {
+    if (NO_ERROR != writeChunk(fd, END_CHUNK, 0, nullptr)) {
         ALOGE("Failed to write end chunk to fd %d", fd.get());
         return UNKNOWN_ERROR;
     }
diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp
index 665dfea..4fb8fa0 100644
--- a/libs/binder/Stability.cpp
+++ b/libs/binder/Stability.cpp
@@ -70,7 +70,7 @@
 }
 
 void Stability::tryMarkCompilationUnit(IBinder* binder) {
-    (void)setRepr(binder, getLocalLevel(), REPR_NONE);
+    std::ignore = setRepr(binder, getLocalLevel(), REPR_NONE);
 }
 
 // after deprecation of the VNDK, these should be aliases. At some point
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 5e18b91..eb73037 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -1009,7 +1009,7 @@
             typename std::enable_if_t<is_specialization_v<CT, std::vector>, bool> = true>
     status_t writeData(const CT& c) {
         using T = first_template_type_t<CT>;  // The T in CT == C<T, ...>
-        if (c.size() >  std::numeric_limits<int32_t>::max()) return BAD_VALUE;
+        if (c.size() > static_cast<size_t>(std::numeric_limits<int32_t>::max())) return BAD_VALUE;
         const auto size = static_cast<int32_t>(c.size());
         writeData(size);
         if constexpr (is_pointer_equivalent_array_v<T>) {
diff --git a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
index 18769b1..8c62924 100644
--- a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
@@ -377,7 +377,7 @@
 
 namespace internal {
 
-static void closeWithError(int fd) {
+inline void closeWithError(int fd) {
     if (fd == -1) return;
     int ret = close(fd);
     if (ret != 0) {
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index ef556d7..725744c 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -59,6 +59,7 @@
     ],
     host_supported: true,
     vendor_available: true,
+    product_available: true,
     target: {
         darwin: {
             enabled: false,
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 6800a8d..bd24a20 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -28,6 +28,11 @@
     cflags: [
         "-Wall",
         "-Werror",
+        "-Wformat",
+        "-Wpessimizing-move",
+        "-Wsign-compare",
+        "-Wunused-result",
+        "-Wzero-as-null-pointer-constant",
     ],
 }
 
diff --git a/libs/binder/tests/RpcTlsUtilsTest.cpp b/libs/binder/tests/RpcTlsUtilsTest.cpp
index 530606c..48e3345 100644
--- a/libs/binder/tests/RpcTlsUtilsTest.cpp
+++ b/libs/binder/tests/RpcTlsUtilsTest.cpp
@@ -52,9 +52,9 @@
             << "\nactual: " << toDebugString(deserializedPkey.get());
 }
 
-INSTANTIATE_TEST_CASE_P(RpcTlsUtilsTest, RpcTlsUtilsKeyTest,
-                        testing::Values(RpcKeyFormat::PEM, RpcKeyFormat::DER),
-                        RpcTlsUtilsKeyTest::PrintParamInfo);
+INSTANTIATE_TEST_SUITE_P(RpcTlsUtilsTest, RpcTlsUtilsKeyTest,
+                         testing::Values(RpcKeyFormat::PEM, RpcKeyFormat::DER),
+                         RpcTlsUtilsKeyTest::PrintParamInfo);
 
 class RpcTlsUtilsCertTest : public testing::TestWithParam<RpcCertificateFormat> {
 public:
@@ -75,9 +75,9 @@
     EXPECT_EQ(0, X509_cmp(cert.get(), deserializedCert.get()));
 }
 
-INSTANTIATE_TEST_CASE_P(RpcTlsUtilsTest, RpcTlsUtilsCertTest,
-                        testing::Values(RpcCertificateFormat::PEM, RpcCertificateFormat::DER),
-                        RpcTlsUtilsCertTest::PrintParamInfo);
+INSTANTIATE_TEST_SUITE_P(RpcTlsUtilsTest, RpcTlsUtilsCertTest,
+                         testing::Values(RpcCertificateFormat::PEM, RpcCertificateFormat::DER),
+                         RpcTlsUtilsCertTest::PrintParamInfo);
 
 class RpcTlsUtilsKeyAndCertTest
       : public testing::TestWithParam<std::tuple<RpcKeyFormat, RpcCertificateFormat>> {
@@ -105,10 +105,10 @@
     EXPECT_EQ(0, X509_cmp(cert.get(), deserializedCert.get()));
 }
 
-INSTANTIATE_TEST_CASE_P(RpcTlsUtilsTest, RpcTlsUtilsKeyAndCertTest,
-                        testing::Combine(testing::Values(RpcKeyFormat::PEM, RpcKeyFormat::DER),
-                                         testing::Values(RpcCertificateFormat::PEM,
-                                                         RpcCertificateFormat::DER)),
-                        RpcTlsUtilsKeyAndCertTest::PrintParamInfo);
+INSTANTIATE_TEST_SUITE_P(RpcTlsUtilsTest, RpcTlsUtilsKeyAndCertTest,
+                         testing::Combine(testing::Values(RpcKeyFormat::PEM, RpcKeyFormat::DER),
+                                          testing::Values(RpcCertificateFormat::PEM,
+                                                          RpcCertificateFormat::DER)),
+                         RpcTlsUtilsKeyAndCertTest::PrintParamInfo);
 
 } // namespace android
diff --git a/libs/binder/tests/binderAllocationLimits.cpp b/libs/binder/tests/binderAllocationLimits.cpp
index 7e0b594..c0c0aae 100644
--- a/libs/binder/tests/binderAllocationLimits.cpp
+++ b/libs/binder/tests/binderAllocationLimits.cpp
@@ -114,12 +114,12 @@
     {
         const auto on_malloc = OnMalloc([&](size_t bytes) {
             mallocs++;
-            EXPECT_EQ(bytes, 40);
+            EXPECT_EQ(bytes, 40u);
         });
 
         imaginary_use = new int[10];
     }
-    EXPECT_EQ(mallocs, 1);
+    EXPECT_EQ(mallocs, 1u);
 }
 
 
@@ -196,9 +196,9 @@
         // Happens to be SM package length. We could switch to forking
         // and registering our own service if it became an issue.
 #if defined(__LP64__)
-        EXPECT_EQ(bytes, 78);
+        EXPECT_EQ(bytes, 78u);
 #else
-        EXPECT_EQ(bytes, 70);
+        EXPECT_EQ(bytes, 70u);
 #endif
     });
 
@@ -206,7 +206,7 @@
     a_binder->getInterfaceDescriptor();
     a_binder->getInterfaceDescriptor();
 
-    EXPECT_EQ(mallocs, 1);
+    EXPECT_EQ(mallocs, 1u);
 }
 
 TEST(BinderAllocation, SmallTransaction) {
@@ -217,11 +217,11 @@
     const auto on_malloc = OnMalloc([&](size_t bytes) {
         mallocs++;
         // Parcel should allocate a small amount by default
-        EXPECT_EQ(bytes, 128);
+        EXPECT_EQ(bytes, 128u);
     });
     manager->checkService(empty_descriptor);
 
-    EXPECT_EQ(mallocs, 1);
+    EXPECT_EQ(mallocs, 1u);
 }
 
 TEST(RpcBinderAllocation, SetupRpcServer) {
@@ -250,8 +250,8 @@
         });
         ASSERT_EQ(OK, remoteBinder->pingBinder());
     }
-    EXPECT_EQ(mallocs, 1);
-    EXPECT_EQ(totalBytes, 40);
+    EXPECT_EQ(mallocs, 1u);
+    EXPECT_EQ(totalBytes, 40u);
 }
 
 int main(int argc, char** argv) {
diff --git a/libs/binder/tests/binderClearBufTest.cpp b/libs/binder/tests/binderClearBufTest.cpp
index e43ee5f..3230a3f 100644
--- a/libs/binder/tests/binderClearBufTest.cpp
+++ b/libs/binder/tests/binderClearBufTest.cpp
@@ -88,7 +88,7 @@
     // the buffer must have at least some length for the string, but we will
     // just check it has some length, to avoid assuming anything about the
     // format
-    EXPECT_GT(replyBuffer.size(), 0);
+    EXPECT_GT(replyBuffer.size(), 0u);
 
     for (size_t i = 0; i < replyBuffer.size(); i++) {
         EXPECT_EQ(replyBuffer[i], '0') << "reply buffer at " << i;
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 1f61f18..9788d9d 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -528,8 +528,8 @@
     EXPECT_EQ(NO_ERROR, IPCThreadState::self()->getProcessFreezeInfo(pid, &sync_received,
                 &async_received));
 
-    EXPECT_EQ(sync_received, 1);
-    EXPECT_EQ(async_received, 0);
+    EXPECT_EQ(sync_received, 1u);
+    EXPECT_EQ(async_received, 0u);
 
     EXPECT_EQ(NO_ERROR, IPCThreadState::self()->freeze(pid, false, 0));
     EXPECT_EQ(NO_ERROR, m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply));
@@ -1238,13 +1238,13 @@
     data.setDataCapacity(1024);
     // Write a bogus object at offset 0 to get an entry in the offset table
     data.writeFileDescriptor(0);
-    EXPECT_EQ(data.objectsCount(), 1);
+    EXPECT_EQ(data.objectsCount(), 1u);
     uint8_t *parcelData = const_cast<uint8_t*>(data.data());
     // And now, overwrite it with the buffer object
     memcpy(parcelData, &obj, sizeof(obj));
     data.setDataSize(sizeof(obj));
 
-    EXPECT_EQ(data.objectsCount(), 1);
+    EXPECT_EQ(data.objectsCount(), 1u);
 
     // Either the kernel should reject this transaction (if it's correct), but
     // if it's not, the server implementation should return an error if it
@@ -1269,7 +1269,7 @@
     data.setDataCapacity(1024);
     // Write a bogus object at offset 0 to get an entry in the offset table
     data.writeFileDescriptor(0);
-    EXPECT_EQ(data.objectsCount(), 1);
+    EXPECT_EQ(data.objectsCount(), 1u);
     uint8_t *parcelData = const_cast<uint8_t *>(data.data());
     // And now, overwrite it with the weak binder
     memcpy(parcelData, &obj, sizeof(obj));
@@ -1279,7 +1279,7 @@
     // test with an object that libbinder will actually try to release
     EXPECT_EQ(OK, data.writeStrongBinder(sp<BBinder>::make()));
 
-    EXPECT_EQ(data.objectsCount(), 2);
+    EXPECT_EQ(data.objectsCount(), 2u);
 
     // send it many times, since previous error was memory corruption, make it
     // more likely that the server crashes
@@ -1648,8 +1648,8 @@
     EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), nullptr),
                 Debuggable(StatusEq(UNEXPECTED_NULL)));
 }
-INSTANTIATE_TEST_CASE_P(BinderLibTest, BinderLibRpcTestP, testing::Bool(),
-                        BinderLibRpcTestP::ParamToString);
+INSTANTIATE_TEST_SUITE_P(BinderLibTest, BinderLibRpcTestP, testing::Bool(),
+                         BinderLibRpcTestP::ParamToString);
 
 class BinderLibTestService : public BBinder {
 public:
diff --git a/libs/binder/tests/binderRpcBenchmark.cpp b/libs/binder/tests/binderRpcBenchmark.cpp
index 4f10d74..865f0ec 100644
--- a/libs/binder/tests/binderRpcBenchmark.cpp
+++ b/libs/binder/tests/binderRpcBenchmark.cpp
@@ -216,7 +216,7 @@
     // by how many binder calls work together (and by factors like the scheduler,
     // thermal throttling, core choice, etc..).
     std::string str = std::string(getpagesize() * 2, 'a');
-    CHECK_EQ(str.size(), getpagesize() * 2);
+    CHECK_EQ(static_cast<ssize_t>(str.size()), getpagesize() * 2);
 
     while (state.KeepRunning()) {
         std::string out;
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 2769a88..c044d39 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -64,12 +64,12 @@
 
 static std::string WaitStatusToString(int wstatus) {
     if (WIFEXITED(wstatus)) {
-        return std::format("exit status {}", WEXITSTATUS(wstatus));
+        return "exit status " + std::to_string(WEXITSTATUS(wstatus));
     }
     if (WIFSIGNALED(wstatus)) {
-        return std::format("term signal {}", WTERMSIG(wstatus));
+        return "term signal " + std::to_string(WTERMSIG(wstatus));
     }
-    return std::format("unexpected state {}", wstatus);
+    return "unexpected state " + std::to_string(wstatus);
 }
 
 static void debugBacktrace(pid_t pid) {
@@ -177,7 +177,7 @@
 
             EXPECT_NE(nullptr, session);
             EXPECT_NE(nullptr, session->state());
-            EXPECT_EQ(0, session->state()->countBinders()) << (session->state()->dump(), "dump:");
+            EXPECT_EQ(0u, session->state()->countBinders()) << (session->state()->dump(), "dump:");
 
             wp<RpcSession> weakSession = session;
             session = nullptr;
@@ -235,7 +235,7 @@
     if (binder::os::sendMessageOnSocket(transportFd, &iov, 1, &fds) < 0) {
         PLOGF("Failed sendMessageOnSocket");
     }
-    return std::move(sockClient);
+    return sockClient;
 }
 #endif // BINDER_RPC_TO_TRUSTY_TEST
 
@@ -263,9 +263,8 @@
     bool noKernel = GetParam().noKernel;
 
     std::string path = GetExecutableDirectory();
-    auto servicePath =
-            std::format("{}/binder_rpc_test_service{}{}", path,
-                        singleThreaded ? "_single_threaded" : "", noKernel ? "_no_kernel" : "");
+    auto servicePath = path + "/binder_rpc_test_service" +
+            (singleThreaded ? "_single_threaded" : "") + (noKernel ? "_no_kernel" : "");
 
     unique_fd bootstrapClientFd, socketFd;
 
@@ -623,7 +622,7 @@
     for (size_t i = 0; i + 1 < kNumQueued; i++) {
         int n;
         proc.rootIface->blockingRecvInt(&n);
-        EXPECT_EQ(n, i);
+        EXPECT_EQ(n, static_cast<ssize_t>(i));
     }
 
     saturateThreadPool(1 + kNumExtraServerThreads, proc.rootIface);
@@ -1148,8 +1147,8 @@
     return ret;
 }
 
-INSTANTIATE_TEST_CASE_P(Trusty, BinderRpc, ::testing::ValuesIn(getTrustyBinderRpcParams()),
-                        BinderRpc::PrintParamInfo);
+INSTANTIATE_TEST_SUITE_P(Trusty, BinderRpc, ::testing::ValuesIn(getTrustyBinderRpcParams()),
+                         BinderRpc::PrintParamInfo);
 #else // BINDER_RPC_TO_TRUSTY_TEST
 bool testSupportVsockLoopback() {
     // We don't need to enable TLS to know if vsock is supported.
@@ -1308,8 +1307,8 @@
     return ret;
 }
 
-INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc, ::testing::ValuesIn(getBinderRpcParams()),
-                        BinderRpc::PrintParamInfo);
+INSTANTIATE_TEST_SUITE_P(PerSocket, BinderRpc, ::testing::ValuesIn(getBinderRpcParams()),
+                         BinderRpc::PrintParamInfo);
 
 class BinderRpcServerRootObject
       : public ::testing::TestWithParam<std::tuple<bool, bool, RpcSecurity>> {};
@@ -1337,9 +1336,9 @@
     EXPECT_EQ((isStrong2 ? binderRaw2 : nullptr), server->getRootObject());
 }
 
-INSTANTIATE_TEST_CASE_P(BinderRpc, BinderRpcServerRootObject,
-                        ::testing::Combine(::testing::Bool(), ::testing::Bool(),
-                                           ::testing::ValuesIn(RpcSecurityValues())));
+INSTANTIATE_TEST_SUITE_P(BinderRpc, BinderRpcServerRootObject,
+                         ::testing::Combine(::testing::Bool(), ::testing::Bool(),
+                                            ::testing::ValuesIn(RpcSecurityValues())));
 
 class OneOffSignal {
 public:
@@ -1384,7 +1383,7 @@
     auto binder = sm->checkService(String16("batteryproperties"));
     ASSERT_NE(nullptr, binder);
     auto descriptor = binder->getInterfaceDescriptor();
-    ASSERT_GE(descriptor.size(), 0);
+    ASSERT_GE(descriptor.size(), 0u);
     ASSERT_EQ(OK, binder->pingBinder());
 
     auto rpcServer = RpcServer::make();
@@ -1468,10 +1467,10 @@
             << "After server->shutdown() returns true, join() did not stop after 2s";
 }
 
-INSTANTIATE_TEST_CASE_P(BinderRpc, BinderRpcServerOnly,
-                        ::testing::Combine(::testing::ValuesIn(RpcSecurityValues()),
-                                           ::testing::ValuesIn(testVersions())),
-                        BinderRpcServerOnly::PrintTestParam);
+INSTANTIATE_TEST_SUITE_P(BinderRpc, BinderRpcServerOnly,
+                         ::testing::Combine(::testing::ValuesIn(RpcSecurityValues()),
+                                            ::testing::ValuesIn(testVersions())),
+                         BinderRpcServerOnly::PrintTestParam);
 
 class RpcTransportTestUtils {
 public:
@@ -2018,9 +2017,9 @@
     server->shutdown();
 }
 
-INSTANTIATE_TEST_CASE_P(BinderRpc, RpcTransportTest,
-                        ::testing::ValuesIn(RpcTransportTest::getRpcTranportTestParams()),
-                        RpcTransportTest::PrintParamInfo);
+INSTANTIATE_TEST_SUITE_P(BinderRpc, RpcTransportTest,
+                         ::testing::ValuesIn(RpcTransportTest::getRpcTranportTestParams()),
+                         RpcTransportTest::PrintParamInfo);
 
 class RpcTransportTlsKeyTest
       : public testing::TestWithParam<
@@ -2075,7 +2074,7 @@
     client.run();
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
         BinderRpc, RpcTransportTlsKeyTest,
         testing::Combine(testing::ValuesIn(testSocketTypes(false /* hasPreconnected*/)),
                          testing::Values(RpcCertificateFormat::PEM, RpcCertificateFormat::DER),
diff --git a/libs/binder/tests/binderRpcTestCommon.h b/libs/binder/tests/binderRpcTestCommon.h
index 8832f1a..acc0373 100644
--- a/libs/binder/tests/binderRpcTestCommon.h
+++ b/libs/binder/tests/binderRpcTestCommon.h
@@ -60,7 +60,6 @@
 #include "../FdUtils.h"
 #include "../RpcState.h" // for debugging
 #include "FileUtils.h"
-#include "format.h"
 #include "utils/Errors.h"
 
 namespace android {
@@ -99,7 +98,7 @@
 }
 
 static inline std::string trustyIpcPort(uint32_t serverVersion) {
-    return std::format("com.android.trusty.binderRpcTestService.V{}", serverVersion);
+    return "com.android.trusty.binderRpcTestService.V" + std::to_string(serverVersion);
 }
 
 enum class SocketType {
@@ -210,7 +209,7 @@
             return RpcTransportCtxFactoryTls::make(std::move(verifier), std::move(auth));
         }
         default:
-            LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", rpcSecurity);
+            LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", static_cast<int>(rpcSecurity));
     }
 }
 
@@ -256,7 +255,7 @@
         mValue.reset();
         lock.unlock();
         mCvEmpty.notify_all();
-        return std::move(v);
+        return v;
     }
 
 private:
diff --git a/libs/binder/tests/binderRpcTestTrusty.cpp b/libs/binder/tests/binderRpcTestTrusty.cpp
index 18751cc..31c0eba 100644
--- a/libs/binder/tests/binderRpcTestTrusty.cpp
+++ b/libs/binder/tests/binderRpcTestTrusty.cpp
@@ -45,7 +45,7 @@
         case RpcSecurity::RAW:
             return RpcTransportCtxFactoryTipcTrusty::make();
         default:
-            LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", rpcSecurity);
+            LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", static_cast<int>(rpcSecurity));
     }
 }
 
@@ -110,8 +110,8 @@
     return ret;
 }
 
-INSTANTIATE_TEST_CASE_P(Trusty, BinderRpc, ::testing::ValuesIn(getTrustyBinderRpcParams()),
-                        BinderRpc::PrintParamInfo);
+INSTANTIATE_TEST_SUITE_P(Trusty, BinderRpc, ::testing::ValuesIn(getTrustyBinderRpcParams()),
+                         BinderRpc::PrintParamInfo);
 
 } // namespace android
 
diff --git a/libs/binder/tests/format.h b/libs/binder/tests/format.h
deleted file mode 100644
index c588de7..0000000
--- a/libs/binder/tests/format.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// TODO(b/302723053): remove this header and replace with <format> once b/175635923 is done
-// ETA for this blocker is 2023-10-27~2023-11-10.
-// Also, remember to remove fmtlib's format.cc from trusty makefiles.
-
-#if __has_include(<format>) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
-#include <format>
-#else
-#include <fmt/format.h>
-
-namespace std {
-using fmt::format;
-}
-#endif
\ No newline at end of file
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 6c45746..2547297 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -87,6 +87,7 @@
         "android/gui/DropInputMode.aidl",
         "android/gui/StalledTransactionInfo.aidl",
         "android/**/TouchOcclusionMode.aidl",
+        "android/gui/TrustedOverlay.aidl",
     ],
 }
 
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 0a28799..c82bde9 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -89,7 +89,7 @@
         frameRateSelectionStrategy(ANATIVEWINDOW_FRAME_RATE_SELECTION_STRATEGY_PROPAGATE),
         fixedTransformHint(ui::Transform::ROT_INVALID),
         autoRefresh(false),
-        isTrustedOverlay(false),
+        trustedOverlay(gui::TrustedOverlay::UNSET),
         bufferCrop(Rect::INVALID_RECT),
         destinationFrame(Rect::INVALID_RECT),
         dropInputMode(gui::DropInputMode::NONE) {
@@ -179,7 +179,7 @@
     SAFE_PARCEL(output.write, stretchEffect);
     SAFE_PARCEL(output.write, bufferCrop);
     SAFE_PARCEL(output.write, destinationFrame);
-    SAFE_PARCEL(output.writeBool, isTrustedOverlay);
+    SAFE_PARCEL(output.writeInt32, static_cast<uint32_t>(trustedOverlay));
 
     SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(dropInputMode));
 
@@ -308,7 +308,9 @@
     SAFE_PARCEL(input.read, stretchEffect);
     SAFE_PARCEL(input.read, bufferCrop);
     SAFE_PARCEL(input.read, destinationFrame);
-    SAFE_PARCEL(input.readBool, &isTrustedOverlay);
+    uint32_t trustedOverlayInt;
+    SAFE_PARCEL(input.readUint32, &trustedOverlayInt);
+    trustedOverlay = static_cast<gui::TrustedOverlay>(trustedOverlayInt);
 
     uint32_t mode;
     SAFE_PARCEL(input.readUint32, &mode);
@@ -674,7 +676,7 @@
     }
     if (other.what & eTrustedOverlayChanged) {
         what |= eTrustedOverlayChanged;
-        isTrustedOverlay = other.isTrustedOverlay;
+        trustedOverlay = other.trustedOverlay;
     }
     if (other.what & eStretchChanged) {
         what |= eStretchChanged;
@@ -779,7 +781,7 @@
     CHECK_DIFF(diff, eFrameRateSelectionStrategyChanged, other, frameRateSelectionStrategy);
     CHECK_DIFF(diff, eFixedTransformHintChanged, other, fixedTransformHint);
     CHECK_DIFF(diff, eAutoRefreshChanged, other, autoRefresh);
-    CHECK_DIFF(diff, eTrustedOverlayChanged, other, isTrustedOverlay);
+    CHECK_DIFF(diff, eTrustedOverlayChanged, other, trustedOverlay);
     CHECK_DIFF(diff, eStretchChanged, other, stretchEffect);
     CHECK_DIFF(diff, eBufferCropChanged, other, bufferCrop);
     CHECK_DIFF(diff, eDestinationFrameChanged, other, destinationFrame);
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 0a85cf8..b420aab 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -2179,6 +2179,13 @@
 
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrustedOverlay(
         const sp<SurfaceControl>& sc, bool isTrustedOverlay) {
+    return setTrustedOverlay(sc,
+                             isTrustedOverlay ? gui::TrustedOverlay::ENABLED
+                                              : gui::TrustedOverlay::UNSET);
+}
+
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrustedOverlay(
+        const sp<SurfaceControl>& sc, gui::TrustedOverlay trustedOverlay) {
     layer_state_t* s = getLayerState(sc);
     if (!s) {
         mStatus = BAD_INDEX;
@@ -2186,7 +2193,7 @@
     }
 
     s->what |= layer_state_t::eTrustedOverlayChanged;
-    s->isTrustedOverlay = isTrustedOverlay;
+    s->trustedOverlay = trustedOverlay;
     return *this;
 }
 
@@ -3118,6 +3125,10 @@
             ->removeWindowInfosListener(windowInfosListener,
                                         ComposerServiceAIDL::getComposerService());
 }
+
+void SurfaceComposerClient::notifyShutdown() {
+    ComposerServiceAIDL::getComposerService()->notifyShutdown();
+}
 // ----------------------------------------------------------------------------
 
 status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs,
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
index 11ccc9c..6d018ea 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -573,4 +573,11 @@
     @nullable StalledTransactionInfo getStalledTransactionInfo(int pid);
 
     SchedulingPolicy getSchedulingPolicy();
+
+    /**
+     * Notifies the SurfaceFlinger that the ShutdownThread is running. When it is called,
+     * transaction traces will be captured and writted into a file.
+     * This method should not block the ShutdownThread therefore it's handled asynchronously.
+     */
+    oneway void notifyShutdown();
 }
diff --git a/libs/gui/android/gui/TrustedOverlay.aidl b/libs/gui/android/gui/TrustedOverlay.aidl
new file mode 100644
index 0000000..06fb5f0
--- /dev/null
+++ b/libs/gui/android/gui/TrustedOverlay.aidl
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2024, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+
+/**
+  * Trusted overlay state prevents layers from being considered as obscuring for
+  * input occlusion detection purposes.
+  *
+  * @hide
+  */
+@Backing(type="int")
+enum TrustedOverlay {
+    /**
+      * The default, layer will inherit the state from its parents. If the parent state is also
+      * unset, the layer will be considered as untrusted.
+      */
+    UNSET,
+
+    /**
+      * Treats this layer and all its children as an untrusted overlay. This will override any
+      * state set by its parent layers.
+      */
+    DISABLED,
+
+    /**
+      * Treats this layer and all its children as a trusted overlay unless the child layer
+      * explicitly disables its trusted state.
+      */
+    ENABLED
+}
diff --git a/libs/gui/include/gui/LayerMetadata.h b/libs/gui/include/gui/LayerMetadata.h
index 7ee291d..9cf62bc 100644
--- a/libs/gui/include/gui/LayerMetadata.h
+++ b/libs/gui/include/gui/LayerMetadata.h
@@ -74,7 +74,6 @@
 } // namespace android::gui
 
 using android::gui::METADATA_ACCESSIBILITY_ID;
-using android::gui::METADATA_CALLING_UID;
 using android::gui::METADATA_DEQUEUE_TIME;
 using android::gui::METADATA_GAME_MODE;
 using android::gui::METADATA_MOUSE_CURSOR;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index ca7acf9..82889ef 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -30,6 +30,7 @@
 
 #include <android/gui/DropInputMode.h>
 #include <android/gui/FocusRequest.h>
+#include <android/gui/TrustedOverlay.h>
 
 #include <ftl/flags.h>
 #include <gui/DisplayCaptureArgs.h>
@@ -385,7 +386,7 @@
 
     // An inherited state that indicates that this surface control and its children
     // should be trusted for input occlusion detection purposes
-    bool isTrustedOverlay;
+    gui::TrustedOverlay trustedOverlay;
 
     // Stretch effect to be applied to this layer
     StretchEffect stretchEffect;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index e2307ed..9712907 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -719,6 +719,8 @@
 
         // Sets that this surface control and its children are trusted overlays for input
         Transaction& setTrustedOverlay(const sp<SurfaceControl>& sc, bool isTrustedOverlay);
+        Transaction& setTrustedOverlay(const sp<SurfaceControl>& sc,
+                                       gui::TrustedOverlay trustedOverlay);
 
         // Queues up transactions using this token in SurfaceFlinger.  By default, all transactions
         // from a client are placed on the same queue. This can be used to prevent multiple
@@ -824,6 +826,8 @@
                     nullptr);
     status_t removeWindowInfosListener(const sp<gui::WindowInfosListener>& windowInfosListener);
 
+    static void notifyShutdown();
+
 protected:
     ReleaseCallbackThread mReleaseCallbackThread;
 
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 6c6a849..43cd0f8 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -985,6 +985,8 @@
         return binder::Status::ok();
     }
 
+    binder::Status notifyShutdown() override { return binder::Status::ok(); }
+
 protected:
     IBinder* onAsBinder() override { return nullptr; }
 
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index deb6253..b640983 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -86,6 +86,22 @@
     // Configures the rendering intent of the output display. This is used for tonemapping.
     aidl::android::hardware::graphics::composer3::RenderIntent renderIntent =
             aidl::android::hardware::graphics::composer3::RenderIntent::TONE_MAP_COLORIMETRIC;
+
+    // Tonemapping strategy to use for each layer. This is only used for tonemapping HDR source
+    // content
+    enum class TonemapStrategy {
+        // Use a tonemapper defined by libtonemap. This may be OEM-defined as of Android 13, aka
+        // undefined.
+        // This is typically a global tonemapper, designed to match what is on screen.
+        Libtonemap,
+        // Use a local tonemapper. Because local tonemapping uses large intermediate allocations,
+        // this
+        // method is primarily recommended for infrequent rendering that does not need to exactly
+        // match
+        // pixels that are on-screen.
+        Local,
+    };
+    TonemapStrategy tonemapStrategy = TonemapStrategy::Libtonemap;
 };
 
 static inline bool operator==(const DisplaySettings& lhs, const DisplaySettings& rhs) {
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 980d913..7207394 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -88,6 +88,21 @@
     PROTECTED = 2,
 };
 
+// Toggles for skipping or enabling priming of particular shaders.
+struct PrimeCacheConfig {
+    bool cacheHolePunchLayer = true;
+    bool cacheSolidLayers = true;
+    bool cacheSolidDimmedLayers = true;
+    bool cacheImageLayers = true;
+    bool cacheImageDimmedLayers = true;
+    bool cacheClippedLayers = true;
+    bool cacheShadowLayers = true;
+    bool cachePIPImageLayers = true;
+    bool cacheTransparentImageDimmedLayers = true;
+    bool cacheClippedDimmedImageLayers = true;
+    bool cacheUltraHDR = true;
+};
+
 class RenderEngine {
 public:
     enum class ContextPriority {
@@ -145,7 +160,7 @@
     // This interface, while still in use until a suitable replacement is built,
     // should be considered deprecated, minus some methods which still may be
     // used to support legacy behavior.
-    virtual std::future<void> primeCache(bool shouldPrimeUltraHDR) = 0;
+    virtual std::future<void> primeCache(PrimeCacheConfig config) = 0;
 
     // dump the extension strings. always call the base class.
     virtual void dump(std::string& result) = 0;
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index a58a65c..a8c242a 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -33,7 +33,7 @@
     RenderEngine();
     ~RenderEngine() override;
 
-    MOCK_METHOD1(primeCache, std::future<void>(bool));
+    MOCK_METHOD1(primeCache, std::future<void>(PrimeCacheConfig));
     MOCK_METHOD1(dump, void(std::string&));
     MOCK_CONST_METHOD0(getMaxTextureSize, size_t());
     MOCK_CONST_METHOD0(getMaxViewportDims, size_t());
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index abe0d9b..d246870 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -630,7 +630,7 @@
 //    kFlushAfterEveryLayer = true
 // in external/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
 //    gPrintSKSL = true
-void Cache::primeShaderCache(SkiaRenderEngine* renderengine, bool shouldPrimeUltraHDR) {
+void Cache::primeShaderCache(SkiaRenderEngine* renderengine, PrimeCacheConfig config) {
     const int previousCount = renderengine->reportShadersCompiled();
     if (previousCount) {
         ALOGD("%d Shaders already compiled before Cache::primeShaderCache ran\n", previousCount);
@@ -694,13 +694,24 @@
                 impl::ExternalTexture>(srcBuffer, *renderengine,
                                        impl::ExternalTexture::Usage::READABLE |
                                                impl::ExternalTexture::Usage::WRITEABLE);
-        drawHolePunchLayer(renderengine, display, dstTexture);
-        drawSolidLayers(renderengine, display, dstTexture);
-        drawSolidLayers(renderengine, p3Display, dstTexture);
-        drawSolidDimmedLayers(renderengine, display, dstTexture);
 
-        drawShadowLayers(renderengine, display, srcTexture);
-        drawShadowLayers(renderengine, p3Display, srcTexture);
+        if (config.cacheHolePunchLayer) {
+            drawHolePunchLayer(renderengine, display, dstTexture);
+        }
+
+        if (config.cacheSolidLayers) {
+            drawSolidLayers(renderengine, display, dstTexture);
+            drawSolidLayers(renderengine, p3Display, dstTexture);
+        }
+
+        if (config.cacheSolidDimmedLayers) {
+            drawSolidDimmedLayers(renderengine, display, dstTexture);
+        }
+
+        if (config.cacheShadowLayers) {
+            drawShadowLayers(renderengine, display, srcTexture);
+            drawShadowLayers(renderengine, p3Display, srcTexture);
+        }
 
         if (renderengine->supportsBackgroundBlur()) {
             drawBlurLayers(renderengine, display, dstTexture);
@@ -737,27 +748,40 @@
         }
 
         for (auto texture : textures) {
-            drawImageLayers(renderengine, display, dstTexture, texture);
+            if (config.cacheImageLayers) {
+                drawImageLayers(renderengine, display, dstTexture, texture);
+            }
 
-            drawImageDimmedLayers(renderengine, display, dstTexture, texture);
-            drawImageDimmedLayers(renderengine, p3Display, dstTexture, texture);
-            drawImageDimmedLayers(renderengine, bt2020Display, dstTexture, texture);
+            if (config.cacheImageDimmedLayers) {
+                drawImageDimmedLayers(renderengine, display, dstTexture, texture);
+                drawImageDimmedLayers(renderengine, p3Display, dstTexture, texture);
+                drawImageDimmedLayers(renderengine, bt2020Display, dstTexture, texture);
+            }
 
-            // Draw layers for b/185569240.
-            drawClippedLayers(renderengine, display, dstTexture, texture);
+            if (config.cacheClippedLayers) {
+                // Draw layers for b/185569240.
+                drawClippedLayers(renderengine, display, dstTexture, texture);
+            }
         }
 
-        drawPIPImageLayer(renderengine, display, dstTexture, externalTexture);
+        if (config.cachePIPImageLayers) {
+            drawPIPImageLayer(renderengine, display, dstTexture, externalTexture);
+        }
 
-        drawTransparentImageDimmedLayers(renderengine, bt2020Display, dstTexture, externalTexture);
-        drawTransparentImageDimmedLayers(renderengine, display, dstTexture, externalTexture);
-        drawTransparentImageDimmedLayers(renderengine, p3Display, dstTexture, externalTexture);
-        drawTransparentImageDimmedLayers(renderengine, p3DisplayEnhance, dstTexture,
-                                         externalTexture);
+        if (config.cacheTransparentImageDimmedLayers) {
+            drawTransparentImageDimmedLayers(renderengine, bt2020Display, dstTexture,
+                                             externalTexture);
+            drawTransparentImageDimmedLayers(renderengine, display, dstTexture, externalTexture);
+            drawTransparentImageDimmedLayers(renderengine, p3Display, dstTexture, externalTexture);
+            drawTransparentImageDimmedLayers(renderengine, p3DisplayEnhance, dstTexture,
+                                             externalTexture);
+        }
 
-        drawClippedDimmedImageLayers(renderengine, bt2020Display, dstTexture, externalTexture);
+        if (config.cacheClippedDimmedImageLayers) {
+            drawClippedDimmedImageLayers(renderengine, bt2020Display, dstTexture, externalTexture);
+        }
 
-        if (shouldPrimeUltraHDR) {
+        if (config.cacheUltraHDR) {
             drawBT2020ClippedImageLayers(renderengine, bt2020Display, dstTexture, externalTexture);
 
             drawBT2020ImageLayers(renderengine, bt2020Display, dstTexture, externalTexture);
diff --git a/libs/renderengine/skia/Cache.h b/libs/renderengine/skia/Cache.h
index 62f6705..259432f 100644
--- a/libs/renderengine/skia/Cache.h
+++ b/libs/renderengine/skia/Cache.h
@@ -16,16 +16,21 @@
 
 #pragma once
 
-namespace android::renderengine::skia {
+namespace android::renderengine {
+
+struct PrimeCacheConfig;
+
+namespace skia {
 
 class SkiaRenderEngine;
 
 class Cache {
 public:
-    static void primeShaderCache(SkiaRenderEngine*, bool shouldPrimeUltraHDR);
+    static void primeShaderCache(SkiaRenderEngine*, PrimeCacheConfig config);
 
 private:
     Cache() = default;
 };
 
-} // namespace android::renderengine::skia
+} // namespace skia
+} // namespace android::renderengine
diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp
index b973211..b64b739 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaRenderEngine.cpp
@@ -245,8 +245,8 @@
 
 using base::StringAppendF;
 
-std::future<void> SkiaRenderEngine::primeCache(bool shouldPrimeUltraHDR) {
-    Cache::primeShaderCache(this, shouldPrimeUltraHDR);
+std::future<void> SkiaRenderEngine::primeCache(PrimeCacheConfig config) {
+    Cache::primeShaderCache(this, config);
     return {};
 }
 
@@ -519,6 +519,11 @@
     }
 
     if (parameters.requiresLinearEffect) {
+        if (parameters.display.tonemapStrategy == DisplaySettings::TonemapStrategy::Local) {
+            // TODO: Apply a local tonemap
+            // fallthrough for now
+        }
+
         auto effect =
                 shaders::LinearEffect{.inputDataspace = parameters.layer.sourceDataspace,
                                       .outputDataspace = parameters.outputDataSpace,
@@ -712,8 +717,7 @@
             [&](const auto& l) { return l.whitePointNits; });
 
     // ...and compute the dimming ratio if dimming is requested
-    const float displayDimmingRatio = display.targetLuminanceNits > 0.f &&
-                    maxLayerWhitePoint > 0.f && display.targetLuminanceNits > maxLayerWhitePoint
+    const float displayDimmingRatio = display.targetLuminanceNits > 0.f && maxLayerWhitePoint > 0.f
             ? maxLayerWhitePoint / display.targetLuminanceNits
             : 1.f;
 
diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h
index 38db810..c8f9241 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.h
+++ b/libs/renderengine/skia/SkiaRenderEngine.h
@@ -62,7 +62,7 @@
     SkiaRenderEngine(Threaded, PixelFormat pixelFormat, BlurAlgorithm);
     ~SkiaRenderEngine() override;
 
-    std::future<void> primeCache(bool shouldPrimeUltraHDR) override final;
+    std::future<void> primeCache(PrimeCacheConfig config) override final;
     void cleanupPostRender() override final;
     bool supportsBackgroundBlur() override final {
         return mBlurFilter != nullptr;
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index cb8b016..4dcaff9 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -3141,7 +3141,9 @@
     }
     initializeRenderEngine();
 
-    auto fut = mRE->primeCache(false);
+    PrimeCacheConfig config;
+    config.cacheUltraHDR = false;
+    auto fut = mRE->primeCache(config);
     if (fut.valid()) {
         fut.wait();
     }
diff --git a/libs/renderengine/tests/RenderEngineThreadedTest.cpp b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
index d56dbb2..bdd9402 100644
--- a/libs/renderengine/tests/RenderEngineThreadedTest.cpp
+++ b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
@@ -25,6 +25,7 @@
 
 namespace android {
 
+using renderengine::PrimeCacheConfig;
 using testing::_;
 using testing::Eq;
 using testing::Mock;
@@ -48,9 +49,25 @@
     mThreadedRE->dump(testString);
 }
 
+MATCHER_P(EqConfig, other, "Equality for prime cache config") {
+    return arg.cacheHolePunchLayer == other.cacheHolePunchLayer &&
+            arg.cacheSolidLayers == other.cacheSolidLayers &&
+            arg.cacheSolidDimmedLayers == other.cacheSolidDimmedLayers &&
+            arg.cacheImageLayers == other.cacheImageLayers &&
+            arg.cacheImageDimmedLayers == other.cacheImageDimmedLayers &&
+            arg.cacheClippedLayers == other.cacheClippedLayers &&
+            arg.cacheShadowLayers == other.cacheShadowLayers &&
+            arg.cachePIPImageLayers == other.cachePIPImageLayers &&
+            arg.cacheTransparentImageDimmedLayers == other.cacheTransparentImageDimmedLayers &&
+            arg.cacheClippedDimmedImageLayers == other.cacheClippedDimmedImageLayers &&
+            arg.cacheUltraHDR == other.cacheUltraHDR;
+}
+
 TEST_F(RenderEngineThreadedTest, primeCache) {
-    EXPECT_CALL(*mRenderEngine, primeCache(false));
-    mThreadedRE->primeCache(false);
+    PrimeCacheConfig config;
+    config.cacheUltraHDR = false;
+    EXPECT_CALL(*mRenderEngine, primeCache(EqConfig(config)));
+    mThreadedRE->primeCache(config);
     // need to call ANY synchronous function after primeCache to ensure that primeCache has
     // completed asynchronously before the test completes execution.
     mThreadedRE->getContextPriority();
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index f4cebc0..d27c151 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -130,7 +130,7 @@
     }
 }
 
-std::future<void> RenderEngineThreaded::primeCache(bool shouldPrimeUltraHDR) {
+std::future<void> RenderEngineThreaded::primeCache(PrimeCacheConfig config) {
     const auto resultPromise = std::make_shared<std::promise<void>>();
     std::future<void> resultFuture = resultPromise->get_future();
     ATRACE_CALL();
@@ -138,20 +138,19 @@
     // for the futures.
     {
         std::lock_guard lock(mThreadMutex);
-        mFunctionCalls.push(
-                [resultPromise, shouldPrimeUltraHDR](renderengine::RenderEngine& instance) {
-                    ATRACE_NAME("REThreaded::primeCache");
-                    if (setSchedFifo(false) != NO_ERROR) {
-                        ALOGW("Couldn't set SCHED_OTHER for primeCache");
-                    }
+        mFunctionCalls.push([resultPromise, config](renderengine::RenderEngine& instance) {
+            ATRACE_NAME("REThreaded::primeCache");
+            if (setSchedFifo(false) != NO_ERROR) {
+                ALOGW("Couldn't set SCHED_OTHER for primeCache");
+            }
 
-                    instance.primeCache(shouldPrimeUltraHDR);
-                    resultPromise->set_value();
+            instance.primeCache(config);
+            resultPromise->set_value();
 
-                    if (setSchedFifo(true) != NO_ERROR) {
-                        ALOGW("Couldn't set SCHED_FIFO for primeCache");
-                    }
-                });
+            if (setSchedFifo(true) != NO_ERROR) {
+                ALOGW("Couldn't set SCHED_FIFO for primeCache");
+            }
+        });
     }
     mCondition.notify_one();
 
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h
index d440c96..d4997d6 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.h
+++ b/libs/renderengine/threaded/RenderEngineThreaded.h
@@ -41,7 +41,7 @@
 
     RenderEngineThreaded(CreateInstanceFactory factory);
     ~RenderEngineThreaded() override;
-    std::future<void> primeCache(bool shouldPrimeUltraHDR) override;
+    std::future<void> primeCache(PrimeCacheConfig config) override;
 
     void dump(std::string& result) override;
 
diff --git a/libs/ui/DisplayIdentification.cpp b/libs/ui/DisplayIdentification.cpp
index 0908ae8..e5af740 100644
--- a/libs/ui/DisplayIdentification.cpp
+++ b/libs/ui/DisplayIdentification.cpp
@@ -320,6 +320,11 @@
 
 std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(
         uint8_t port, const DisplayIdentificationData& data) {
+    if (data.empty()) {
+        ALOGI("Display identification data is empty.");
+        return {};
+    }
+
     if (!isEdid(data)) {
         ALOGE("Display identification data has unknown format.");
         return {};
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
index 0c58dab..bca9d91 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
@@ -138,13 +138,14 @@
 
         // Assign pointer id using tracking id if available.
         if (mHavePointerIds) {
-            int32_t trackingId = inSlot.getTrackingId();
+            const int32_t trackingId = inSlot.getTrackingId();
             int32_t id = -1;
             if (trackingId >= 0) {
                 for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty();) {
                     uint32_t n = idBits.clearFirstMarkedBit();
                     if (mPointerTrackingIdMap[n] == trackingId) {
                         id = n;
+                        break;
                     }
                 }
 
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 70ca702..31b7f88 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -1273,7 +1273,10 @@
                 } else {
                     int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
                     disconnectDynamicSensor(handle, activeConnections);
-                    device.cleanupDisconnectedDynamicSensor(handle);
+                    if (sensorservice_flags::
+                            sensor_service_clear_dynamic_sensor_data_at_the_end()) {
+                      device.cleanupDisconnectedDynamicSensor(handle);
+                    }
                 }
             }
         }
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 3bf0eaa..38cf053 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -485,11 +485,11 @@
     }
 }
 
-void DisplayDevice::updateRefreshRateOverlayRate(Fps vsyncRate, Fps renderFps, bool setByHwc) {
+void DisplayDevice::updateRefreshRateOverlayRate(Fps refreshRate, Fps renderFps, bool setByHwc) {
     ATRACE_CALL();
     if (mRefreshRateOverlay) {
         if (!mRefreshRateOverlay->isSetByHwc() || setByHwc) {
-            mRefreshRateOverlay->changeRefreshRate(vsyncRate, renderFps);
+            mRefreshRateOverlay->changeRefreshRate(refreshRate, renderFps);
         } else {
             mRefreshRateOverlay->changeRenderRate(renderFps);
         }
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index c2d09c9..b339bc6 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -226,7 +226,7 @@
     // Enables an overlay to be displayed with the current refresh rate
     void enableRefreshRateOverlay(bool enable, bool setByHwc, bool showSpinner, bool showRenderRate,
                                   bool showInMiddle) REQUIRES(kMainThreadContext);
-    void updateRefreshRateOverlayRate(Fps vsyncRate, Fps renderFps, bool setByHwc = false);
+    void updateRefreshRateOverlayRate(Fps refreshRate, Fps renderFps, bool setByHwc = false);
     bool isRefreshRateOverlayEnabled() const { return mRefreshRateOverlay != nullptr; }
     bool onKernelTimerChanged(std::optional<DisplayModeId>, bool timerExpired);
 
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index c9ed157..2596a25 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -1172,7 +1172,7 @@
                     (static_cast<float>(mSurfaceFlingerPredictions.presentTime) -
                      kThresh * static_cast<float>(mRenderRate.getPeriodNsecs())) &&
             static_cast<float>(surfaceFrame->getPredictions().presentTime) >=
-                    (static_cast<float>(previousPredictionPresentTime) -
+                    (static_cast<float>(previousPredictionPresentTime) +
                      kThresh * static_cast<float>(mRenderRate.getPeriodNsecs())) &&
             // sf skipped frame is not considered if app is self janked
             !surfaceFrame->isSelfJanky()) {
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
index eef8dff..398e64a 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
@@ -84,7 +84,7 @@
     // is a mirror root
     bool ignoreLocalTransform;
     gui::DropInputMode dropInputMode;
-    bool isTrustedOverlay;
+    gui::TrustedOverlay trustedOverlay;
     gui::GameMode gameMode;
     scheduler::LayerInfo::FrameRate frameRate;
     scheduler::LayerInfo::FrameRate inheritedFrameRate;
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index f10bb33..6d4b0b5 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -22,6 +22,7 @@
 #include <numeric>
 #include <optional>
 
+#include <common/FlagManager.h>
 #include <ftl/small_map.h>
 #include <gui/TraceUtils.h>
 #include <ui/DisplayMap.h>
@@ -313,21 +314,6 @@
     }
 }
 
-void updateMetadataAndGameMode(LayerSnapshot& snapshot, const RequestedLayerState& requested,
-                               const LayerSnapshotBuilder::Args& args,
-                               const LayerSnapshot& parentSnapshot) {
-    if (snapshot.changes.test(RequestedLayerState::Changes::GameMode)) {
-        snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE)
-                ? requested.gameMode
-                : parentSnapshot.gameMode;
-    }
-    updateMetadata(snapshot, requested, args);
-    if (args.includeMetadata) {
-        snapshot.layerMetadata = parentSnapshot.layerMetadata;
-        snapshot.layerMetadata.merge(requested.metadata);
-    }
-}
-
 void clearChanges(LayerSnapshot& snapshot) {
     snapshot.changes.clear();
     snapshot.clientChanges = 0;
@@ -373,7 +359,7 @@
     snapshot.relativeLayerMetadata.mMap.clear();
     snapshot.inputInfo.touchOcclusionMode = gui::TouchOcclusionMode::BLOCK_UNTRUSTED;
     snapshot.dropInputMode = gui::DropInputMode::NONE;
-    snapshot.isTrustedOverlay = false;
+    snapshot.trustedOverlay = gui::TrustedOverlay::UNSET;
     snapshot.gameMode = gui::GameMode::Unsupported;
     snapshot.frameRate = {};
     snapshot.fixedTransformHint = ui::Transform::ROT_INVALID;
@@ -750,7 +736,19 @@
     }
 
     if (forceUpdate || snapshot.clientChanges & layer_state_t::eTrustedOverlayChanged) {
-        snapshot.isTrustedOverlay = parentSnapshot.isTrustedOverlay || requested.isTrustedOverlay;
+        switch (requested.trustedOverlay) {
+            case gui::TrustedOverlay::UNSET:
+                snapshot.trustedOverlay = parentSnapshot.trustedOverlay;
+                break;
+            case gui::TrustedOverlay::DISABLED:
+                snapshot.trustedOverlay = FlagManager::getInstance().override_trusted_overlay()
+                        ? requested.trustedOverlay
+                        : parentSnapshot.trustedOverlay;
+                break;
+            case gui::TrustedOverlay::ENABLED:
+                snapshot.trustedOverlay = requested.trustedOverlay;
+                break;
+        }
     }
 
     if (snapshot.isHiddenByPolicyFromParent &&
@@ -761,11 +759,6 @@
                                  RequestedLayerState::Changes::Input)) {
             updateInput(snapshot, requested, parentSnapshot, path, args);
         }
-        if (forceUpdate ||
-            (args.includeMetadata &&
-             snapshot.changes.test(RequestedLayerState::Changes::Metadata))) {
-            updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot);
-        }
         return;
     }
 
@@ -805,8 +798,15 @@
         }
     }
 
-    if (forceUpdate || snapshot.changes.test(RequestedLayerState::Changes::Metadata)) {
-        updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot);
+    if (forceUpdate || snapshot.changes.test(RequestedLayerState::Changes::GameMode)) {
+        snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE)
+                ? requested.gameMode
+                : parentSnapshot.gameMode;
+        updateMetadata(snapshot, requested, args);
+        if (args.includeMetadata) {
+            snapshot.layerMetadata = parentSnapshot.layerMetadata;
+            snapshot.layerMetadata.merge(requested.metadata);
+        }
     }
 
     if (forceUpdate || snapshot.clientChanges & layer_state_t::eFixedTransformHintChanged ||
@@ -1125,7 +1125,7 @@
 
     // Inherit the trusted state from the parent hierarchy, but don't clobber the trusted state
     // if it was set by WM for a known system overlay
-    if (snapshot.isTrustedOverlay) {
+    if (snapshot.trustedOverlay == gui::TrustedOverlay::ENABLED) {
         snapshot.inputInfo.inputConfig |= InputConfig::TRUSTED_OVERLAY;
     }
 
@@ -1175,15 +1175,6 @@
     }
 }
 
-void LayerSnapshotBuilder::forEachSnapshot(const Visitor& visitor,
-                                           const ConstPredicate& predicate) {
-    for (int i = 0; i < mNumInterestingSnapshots; i++) {
-        std::unique_ptr<LayerSnapshot>& snapshot = mSnapshots.at((size_t)i);
-        if (!predicate(*snapshot)) continue;
-        visitor(snapshot);
-    }
-}
-
 void LayerSnapshotBuilder::forEachInputSnapshot(const ConstVisitor& visitor) const {
     for (int i = mNumInterestingSnapshots - 1; i >= 0; i--) {
         LayerSnapshot& snapshot = *mSnapshots[(size_t)i];
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
index dbbad76..1cec018 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
@@ -86,11 +86,6 @@
     // Visit each visible snapshot in z-order and move the snapshot if needed
     void forEachVisibleSnapshot(const Visitor& visitor);
 
-    typedef std::function<bool(const LayerSnapshot& snapshot)> ConstPredicate;
-    // Visit each snapshot that satisfies the predicate and move the snapshot if needed with visible
-    // snapshots in z-order
-    void forEachSnapshot(const Visitor& visitor, const ConstPredicate& predicate);
-
     // Visit each snapshot interesting to input reverse z-order
     void forEachInputSnapshot(const ConstVisitor& visitor) const;
 
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index db515e1..3e8d740 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -118,7 +118,7 @@
     shadowRadius = 0.f;
     fixedTransformHint = ui::Transform::ROT_INVALID;
     destinationFrame.makeInvalid();
-    isTrustedOverlay = false;
+    trustedOverlay = gui::TrustedOverlay::UNSET;
     dropInputMode = gui::DropInputMode::NONE;
     dimmingEnabled = true;
     defaultFrameRateCompatibility = static_cast<int8_t>(scheduler::FrameRateCompatibility::Default);
@@ -328,7 +328,6 @@
                 changes |= RequestedLayerState::Changes::GameMode;
             }
         }
-        changes |= RequestedLayerState::Changes::Metadata;
     }
     if (clientState.what & layer_state_t::eFrameRateChanged) {
         const auto compatibility =
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 363b35c..6b97e2f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -3902,7 +3902,7 @@
     }
 
     if (s.what & layer_state_t::eTrustedOverlayChanged) {
-        if (mDrawingState.isTrustedOverlay != s.isTrustedOverlay) {
+        if (mDrawingState.isTrustedOverlay != (s.trustedOverlay == gui::TrustedOverlay::ENABLED)) {
             ATRACE_FORMAT_INSTANT("%s: false [eTrustedOverlayChanged changed]", __func__);
             return false;
         }
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index 753886a..496033b 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -382,7 +382,8 @@
     layerInfo->set_corner_radius(
             (snapshot.roundedCorner.radius.x + snapshot.roundedCorner.radius.y) / 2.0);
     layerInfo->set_background_blur_radius(snapshot.backgroundBlurRadius);
-    layerInfo->set_is_trusted_overlay(snapshot.isTrustedOverlay);
+    layerInfo->set_is_trusted_overlay(snapshot.trustedOverlay == gui::TrustedOverlay::ENABLED);
+    // TODO(b/339701674) update protos
     LayerProtoHelper::writeToProtoDeprecated(transform, layerInfo->mutable_transform());
     LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
                                            [&]() { return layerInfo->mutable_position(); });
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index b960e33..b40f332 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -28,7 +28,7 @@
 
 namespace android {
 
-auto RefreshRateOverlay::draw(int vsyncRate, int renderFps, SkColor color,
+auto RefreshRateOverlay::draw(int refreshRate, int renderFps, SkColor color,
                               ui::Transform::RotationFlags rotation, ftl::Flags<Features> features)
         -> Buffers {
     const size_t loopCount = features.test(Features::Spinner) ? 6 : 1;
@@ -71,7 +71,7 @@
         canvas->setMatrix(canvasTransform);
 
         int left = 0;
-        drawNumber(vsyncRate, left, color, *canvas);
+        drawNumber(refreshRate, left, color, *canvas);
         left += 3 * (kDigitWidth + kDigitSpace);
         if (features.test(Features::Spinner)) {
             switch (i) {
@@ -171,7 +171,7 @@
     return mSurfaceControl != nullptr;
 }
 
-auto RefreshRateOverlay::getOrCreateBuffers(Fps vsyncRate, Fps renderFps) -> const Buffers& {
+auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps) -> const Buffers& {
     static const Buffers kNoBuffers;
     if (!mSurfaceControl) return kNoBuffers;
 
@@ -198,16 +198,16 @@
     createTransaction().setTransform(mSurfaceControl->get(), transform).apply();
 
     BufferCache::const_iterator it =
-            mBufferCache.find({vsyncRate.getIntValue(), renderFps.getIntValue(), transformHint});
+            mBufferCache.find({refreshRate.getIntValue(), renderFps.getIntValue(), transformHint});
     if (it == mBufferCache.end()) {
         // HWC minFps is not known by the framework in order
         // to consider lower rates we set minFps to 0.
         const int minFps = isSetByHwc() ? 0 : mFpsRange.min.getIntValue();
         const int maxFps = mFpsRange.max.getIntValue();
 
-        // Clamp to the range. The current vsyncRate may be outside of this range if the display
+        // Clamp to the range. The current refreshRate may be outside of this range if the display
         // has changed its set of supported refresh rates.
-        const int displayIntFps = std::clamp(vsyncRate.getIntValue(), minFps, maxFps);
+        const int displayIntFps = std::clamp(refreshRate.getIntValue(), minFps, maxFps);
         const int renderIntFps = renderFps.getIntValue();
 
         // Ensure non-zero range to avoid division by zero.
@@ -260,25 +260,26 @@
     createTransaction().setLayerStack(mSurfaceControl->get(), stack).apply();
 }
 
-void RefreshRateOverlay::changeRefreshRate(Fps vsyncRate, Fps renderFps) {
-    mVsyncRate = vsyncRate;
+void RefreshRateOverlay::changeRefreshRate(Fps refreshRate, Fps renderFps) {
+    mRefreshRate = refreshRate;
     mRenderFps = renderFps;
-    const auto buffer = getOrCreateBuffers(vsyncRate, renderFps)[mFrame];
+    const auto buffer = getOrCreateBuffers(refreshRate, renderFps)[mFrame];
     createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply();
 }
 
 void RefreshRateOverlay::changeRenderRate(Fps renderFps) {
-    if (mFeatures.test(Features::RenderRate) && mVsyncRate && FlagManager::getInstance().misc1()) {
+    if (mFeatures.test(Features::RenderRate) && mRefreshRate &&
+        FlagManager::getInstance().misc1()) {
         mRenderFps = renderFps;
-        const auto buffer = getOrCreateBuffers(*mVsyncRate, renderFps)[mFrame];
+        const auto buffer = getOrCreateBuffers(*mRefreshRate, renderFps)[mFrame];
         createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply();
     }
 }
 
 void RefreshRateOverlay::animate() {
-    if (!mFeatures.test(Features::Spinner) || !mVsyncRate) return;
+    if (!mFeatures.test(Features::Spinner) || !mRefreshRate) return;
 
-    const auto& buffers = getOrCreateBuffers(*mVsyncRate, *mRenderFps);
+    const auto& buffers = getOrCreateBuffers(*mRefreshRate, *mRenderFps);
     mFrame = (mFrame + 1) % buffers.size();
     const auto buffer = buffers[mFrame];
     createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply();
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index 0fec470..93ec36e 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -74,12 +74,12 @@
     SurfaceComposerClient::Transaction createTransaction() const;
 
     struct Key {
-        int vsyncRate;
+        int refreshRate;
         int renderFps;
         ui::Transform::RotationFlags flags;
 
         bool operator==(Key other) const {
-            return vsyncRate == other.vsyncRate && renderFps == other.renderFps &&
+            return refreshRate == other.refreshRate && renderFps == other.renderFps &&
                     flags == other.flags;
         }
     };
@@ -87,7 +87,7 @@
     using BufferCache = ftl::SmallMap<Key, Buffers, 9>;
     BufferCache mBufferCache;
 
-    std::optional<Fps> mVsyncRate;
+    std::optional<Fps> mRefreshRate;
     std::optional<Fps> mRenderFps;
     size_t mFrame = 0;
 
diff --git a/services/surfaceflinger/ScreenCaptureOutput.cpp b/services/surfaceflinger/ScreenCaptureOutput.cpp
index dd03366..8bb72b8 100644
--- a/services/surfaceflinger/ScreenCaptureOutput.cpp
+++ b/services/surfaceflinger/ScreenCaptureOutput.cpp
@@ -30,7 +30,7 @@
             ScreenCaptureOutput, compositionengine::CompositionEngine, const RenderArea&,
             const compositionengine::Output::ColorProfile&,
             bool>(args.compositionEngine, args.renderArea, args.colorProfile, args.regionSampling,
-                  args.dimInGammaSpaceForEnhancedScreenshots);
+                  args.dimInGammaSpaceForEnhancedScreenshots, args.enableLocalTonemapping);
     output->editState().isSecure = args.renderArea.isSecure();
     output->editState().isProtected = args.isProtected;
     output->setCompositionEnabled(true);
@@ -63,11 +63,13 @@
 
 ScreenCaptureOutput::ScreenCaptureOutput(
         const RenderArea& renderArea, const compositionengine::Output::ColorProfile& colorProfile,
-        bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots)
+        bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots,
+        bool enableLocalTonemapping)
       : mRenderArea(renderArea),
         mColorProfile(colorProfile),
         mRegionSampling(regionSampling),
-        mDimInGammaSpaceForEnhancedScreenshots(dimInGammaSpaceForEnhancedScreenshots) {}
+        mDimInGammaSpaceForEnhancedScreenshots(dimInGammaSpaceForEnhancedScreenshots),
+        mEnableLocalTonemapping(enableLocalTonemapping) {}
 
 void ScreenCaptureOutput::updateColorProfile(const compositionengine::CompositionRefreshArgs&) {
     auto& outputState = editState();
@@ -88,6 +90,11 @@
                 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF;
     }
 
+    if (mEnableLocalTonemapping) {
+        clientCompositionDisplay.tonemapStrategy =
+                renderengine::DisplaySettings::TonemapStrategy::Local;
+    }
+
     return clientCompositionDisplay;
 }
 
diff --git a/services/surfaceflinger/ScreenCaptureOutput.h b/services/surfaceflinger/ScreenCaptureOutput.h
index 069f458..c233ead 100644
--- a/services/surfaceflinger/ScreenCaptureOutput.h
+++ b/services/surfaceflinger/ScreenCaptureOutput.h
@@ -39,6 +39,7 @@
     bool treat170mAsSrgb;
     bool dimInGammaSpaceForEnhancedScreenshots;
     bool isProtected = false;
+    bool enableLocalTonemapping = false;
 };
 
 // ScreenCaptureOutput is used to compose a set of layers into a preallocated buffer.
@@ -49,7 +50,8 @@
 public:
     ScreenCaptureOutput(const RenderArea& renderArea,
                         const compositionengine::Output::ColorProfile& colorProfile,
-                        bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots);
+                        bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots,
+                        bool enableLocalTonemapping);
 
     void updateColorProfile(const compositionengine::CompositionRefreshArgs&) override;
 
@@ -67,6 +69,7 @@
     const compositionengine::Output::ColorProfile& mColorProfile;
     const bool mRegionSampling;
     const bool mDimInGammaSpaceForEnhancedScreenshots;
+    const bool mEnableLocalTonemapping;
 };
 
 std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutputArgs);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b2ca572..5f81cd4 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -944,9 +944,34 @@
         }
 
         mRenderEnginePrimeCacheFuture.callOnce([this] {
-            const bool shouldPrimeUltraHDR =
+            renderengine::PrimeCacheConfig config;
+            config.cacheHolePunchLayer =
+                    base::GetBoolProperty("debug.sf.prime_shader_cache.hole_punch"s, true);
+            config.cacheSolidLayers =
+                    base::GetBoolProperty("debug.sf.prime_shader_cache.solid_layers"s, true);
+            config.cacheSolidDimmedLayers =
+                    base::GetBoolProperty("debug.sf.prime_shader_cache.solid_dimmed_layers"s, true);
+            config.cacheImageLayers =
+                    base::GetBoolProperty("debug.sf.prime_shader_cache.image_layers"s, true);
+            config.cacheImageDimmedLayers =
+                    base::GetBoolProperty("debug.sf.prime_shader_cache.image_dimmed_layers"s, true);
+            config.cacheClippedLayers =
+                    base::GetBoolProperty("debug.sf.prime_shader_cache.clipped_layers"s, true);
+            config.cacheShadowLayers =
+                    base::GetBoolProperty("debug.sf.prime_shader_cache.shadow_layers"s, true);
+            config.cachePIPImageLayers =
+                    base::GetBoolProperty("debug.sf.prime_shader_cache.pip_image_layers"s, true);
+            config.cacheTransparentImageDimmedLayers = base::
+                    GetBoolProperty("debug.sf.prime_shader_cache.transparent_image_dimmed_layers"s,
+                                    true);
+            config.cacheClippedDimmedImageLayers = base::
+                    GetBoolProperty("debug.sf.prime_shader_cache.clipped_dimmed_image_layers"s,
+                                    true);
+            // ro.surface_flinger.prime_chader_cache.ultrahdr exists as a previous ro property
+            // which we maintain for backwards compatibility.
+            config.cacheUltraHDR =
                     base::GetBoolProperty("ro.surface_flinger.prime_shader_cache.ultrahdr"s, false);
-            return getRenderEngine().primeCache(shouldPrimeUltraHDR);
+            return getRenderEngine().primeCache(config);
         });
 
         if (setSchedFifo(true) != NO_ERROR) {
@@ -988,8 +1013,9 @@
                         ALOGD("TransactionTraceWriter: file=%s already exists", filename.c_str());
                         return;
                     }
-                    mTransactionTracing->flush();
+                    ALOGD("TransactionTraceWriter: writing file=%s", filename.c_str());
                     mTransactionTracing->writeToFile(filename);
+                    mTransactionTracing->flush();
                 };
                 if (std::this_thread::get_id() == mMainThreadId) {
                     writeFn();
@@ -1414,12 +1440,11 @@
     }
 }
 
-bool SurfaceFlinger::initiateDisplayModeChanges() {
+void SurfaceFlinger::initiateDisplayModeChanges() {
     ATRACE_CALL();
 
     std::optional<PhysicalDisplayId> displayToUpdateImmediately;
 
-    bool mustComposite = false;
     for (const auto& [id, physical] : mPhysicalDisplays) {
         const auto display = getDisplayDeviceLocked(id);
         if (!display) continue;
@@ -1471,11 +1496,7 @@
         mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline);
 
         if (outTimeline.refreshRequired) {
-            if (FlagManager::getInstance().vrr_bugfix_24q4()) {
-                mustComposite = true;
-            } else {
-                scheduleComposite(FrameHint::kNone);
-            }
+            scheduleComposite(FrameHint::kNone);
         } else {
             // TODO(b/255635711): Remove `displayToUpdateImmediately` to `finalizeDisplayModeChange`
             // for all displays. This was only needed when the loop iterated over `mDisplays` rather
@@ -1493,8 +1514,6 @@
             applyActiveMode(display);
         }
     }
-
-    return mustComposite;
 }
 
 void SurfaceFlinger::disableExpensiveRendering() {
@@ -2236,12 +2255,12 @@
                                                    kMainThreadContext) {
         if (const auto displayIdOpt = getHwComposer().toPhysicalDisplayId(data.display)) {
             if (const auto display = getDisplayDeviceLocked(*displayIdOpt)) {
-                const Fps fps = Fps::fromPeriodNsecs(getHwComposer().getComposer()->isVrrSupported()
-                                                             ? data.refreshPeriodNanos
-                                                             : data.vsyncPeriodNanos);
-                ATRACE_FORMAT("%s Fps %d", whence, fps.getIntValue());
-                display->updateRefreshRateOverlayRate(fps, display->getActiveMode().fps,
-                                                      /* setByHwc */ true);
+                const Fps refreshRate = Fps::fromPeriodNsecs(
+                        getHwComposer().getComposer()->isVrrSupported() ? data.refreshPeriodNanos
+                                                                        : data.vsyncPeriodNanos);
+                ATRACE_FORMAT("%s refresh rate = %d", whence, refreshRate.getIntValue());
+                display->updateRefreshRateOverlayRate(refreshRate, display->getActiveMode().fps,
+                                                      /* showRefreshRate */ true);
             }
         }
     }));
@@ -2674,7 +2693,7 @@
                                                         ? &mLayerHierarchyBuilder.getHierarchy()
                                                         : nullptr,
                                                 updateAttachedChoreographer);
-        mustComposite |= initiateDisplayModeChanges();
+        initiateDisplayModeChanges();
     }
 
     updateCursorAsync();
@@ -5692,7 +5711,7 @@
         if (layer->setHdrMetadata(s.hdrMetadata)) flags |= eTraversalNeeded;
     }
     if (what & layer_state_t::eTrustedOverlayChanged) {
-        if (layer->setTrustedOverlay(s.isTrustedOverlay)) {
+        if (layer->setTrustedOverlay(s.trustedOverlay == gui::TrustedOverlay::ENABLED)) {
             flags |= eTraversalNeeded;
         }
     }
@@ -6503,12 +6522,17 @@
         uint8_t port;
         DisplayIdentificationData data;
         if (!getHwComposer().getDisplayIdentificationData(*hwcDisplayId, &port, &data)) {
-            result.append("no identification data\n");
+            result.append("no display identification data\n");
+            continue;
+        }
+
+        if (data.empty()) {
+            result.append("empty display identification data\n");
             continue;
         }
 
         if (!isEdid(data)) {
-            result.append("unknown identification data\n");
+            result.append("unknown format for display identification data\n");
             continue;
         }
 
@@ -8307,6 +8331,9 @@
 
     captureResults.capturedDataspace = requestedDataspace;
 
+    const bool enableLocalTonemapping = FlagManager::getInstance().local_tonemap_screenshots() &&
+            !renderArea->getHintForSeamlessTransition();
+
     {
         Mutex::Autolock lock(mStateLock);
         const DisplayDevice* display = nullptr;
@@ -8340,16 +8367,19 @@
                 displayBrightnessNits = sdrWhitePointNits;
             } else {
                 displayBrightnessNits = state.displayBrightnessNits;
-                // Only clamp the display brightness if this is not a seamless transition. Otherwise
-                // for seamless transitions it's important to match the current display state as the
-                // buffer will be shown under these same conditions, and we want to avoid any
-                // flickers
-                if (sdrWhitePointNits > 1.0f && !renderArea->getHintForSeamlessTransition()) {
-                    // Restrict the amount of HDR "headroom" in the screenshot to avoid over-dimming
-                    // the SDR portion. 2.0 chosen by experimentation
-                    constexpr float kMaxScreenshotHeadroom = 2.0f;
-                    displayBrightnessNits = std::min(sdrWhitePointNits * kMaxScreenshotHeadroom,
-                                                     displayBrightnessNits);
+
+                if (!enableLocalTonemapping) {
+                    // Only clamp the display brightness if this is not a seamless transition.
+                    // Otherwise for seamless transitions it's important to match the current
+                    // display state as the buffer will be shown under these same conditions, and we
+                    // want to avoid any flickers
+                    if (sdrWhitePointNits > 1.0f && !renderArea->getHintForSeamlessTransition()) {
+                        // Restrict the amount of HDR "headroom" in the screenshot to avoid
+                        // over-dimming the SDR portion. 2.0 chosen by experimentation
+                        constexpr float kMaxScreenshotHeadroom = 2.0f;
+                        displayBrightnessNits = std::min(sdrWhitePointNits * kMaxScreenshotHeadroom,
+                                                         displayBrightnessNits);
+                    }
                 }
             }
 
@@ -8381,7 +8411,8 @@
     auto present = [this, buffer = capturedBuffer, dataspace = captureResults.capturedDataspace,
                     sdrWhitePointNits, displayBrightnessNits, grayscale, isProtected,
                     layerFEs = copyLayerFEs(), layerStack, regionSampling,
-                    renderArea = std::move(renderArea), renderIntent]() -> FenceResult {
+                    renderArea = std::move(renderArea), renderIntent,
+                    enableLocalTonemapping]() -> FenceResult {
         std::unique_ptr<compositionengine::CompositionEngine> compositionEngine =
                 mFactory.createCompositionEngine();
         compositionEngine->setRenderEngine(mRenderEngine.get());
@@ -8390,7 +8421,11 @@
                                                              .renderIntent = renderIntent};
 
         float targetBrightness = 1.0f;
-        if (dataspace == ui::Dataspace::BT2020_HLG) {
+        if (enableLocalTonemapping) {
+            // Boost the whole scene so that SDR white is at 1.0 while still communicating the hdr
+            // sdr ratio via display brightness / sdrWhite nits.
+            targetBrightness = sdrWhitePointNits / displayBrightnessNits;
+        } else if (dataspace == ui::Dataspace::BT2020_HLG) {
             const float maxBrightnessNits = displayBrightnessNits / sdrWhitePointNits * 203;
             // With a low dimming ratio, don't fit the entire curve. Otherwise mixed content
             // will appear way too bright.
@@ -8416,7 +8451,8 @@
                                         .treat170mAsSrgb = mTreat170mAsSrgb,
                                         .dimInGammaSpaceForEnhancedScreenshots =
                                                 dimInGammaSpaceForEnhancedScreenshots,
-                                        .isProtected = isProtected});
+                                        .isProtected = isProtected,
+                                        .enableLocalTonemapping = enableLocalTonemapping});
 
         const float colorSaturation = grayscale ? 0 : 1;
         compositionengine::CompositionRefreshArgs refreshArgs{
@@ -8815,7 +8851,8 @@
                     const auto status =
                             getHwComposer().setRefreshRateChangedCallbackDebugEnabled(id, enable);
                     if (status != NO_ERROR) {
-                        ALOGE("Error updating the refresh rate changed callback debug enabled");
+                        ALOGE("Error %s refresh rate changed callback debug",
+                              enable ? "enabling" : "disabling");
                         enableOverlay(/*setByHwc*/ false);
                     }
                 }
@@ -9202,9 +9239,7 @@
     std::vector<std::pair<Layer*, LayerFE*>> layers;
     if (mLayerLifecycleManagerEnabled) {
         nsecs_t currentTime = systemTime();
-        const bool needsMetadata = mCompositionEngine->getFeatureFlags().test(
-                compositionengine::Feature::kSnapshotLayerMetadata);
-        mLayerSnapshotBuilder.forEachSnapshot(
+        mLayerSnapshotBuilder.forEachVisibleSnapshot(
                 [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD(
                         kMainThreadContext) {
                     if (cursorOnly &&
@@ -9227,12 +9262,6 @@
                     layerFE->mSnapshot = std::move(snapshot);
                     refreshArgs.layers.push_back(layerFE);
                     layers.emplace_back(legacyLayer.get(), layerFE.get());
-                },
-                [needsMetadata](const frontend::LayerSnapshot& snapshot) {
-                    return snapshot.isVisible ||
-                            (needsMetadata &&
-                             snapshot.changes.test(
-                                     frontend::RequestedLayerState::Changes::Metadata));
                 });
     }
     if (!mLayerLifecycleManagerEnabled) {
@@ -10324,6 +10353,11 @@
     return gui::getSchedulingPolicy(outPolicy);
 }
 
+binder::Status SurfaceComposerAIDL::notifyShutdown() {
+    TransactionTraceWriter::getInstance().invoke("systemShutdown_", /* overwrite= */ false);
+    return ::android::binder::Status::ok();
+}
+
 status_t SurfaceComposerAIDL::checkAccessPermission(bool usePermissionCache) {
     if (!mFlinger->callingThreadHasUnscopedSurfaceFlingerAccess(usePermissionCache)) {
         IPCThreadState* ipc = IPCThreadState::self();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index d56072a..8a39016 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -737,7 +737,7 @@
     status_t setActiveModeFromBackdoor(const sp<display::DisplayToken>&, DisplayModeId, Fps minFps,
                                        Fps maxFps);
 
-    bool initiateDisplayModeChanges() REQUIRES(mStateLock, kMainThreadContext);
+    void initiateDisplayModeChanges() REQUIRES(mStateLock, kMainThreadContext);
     void finalizeDisplayModeChange(DisplayDevice&) REQUIRES(mStateLock, kMainThreadContext);
 
     // TODO(b/241285191): Replace DisplayDevice with DisplayModeRequest, and move to Scheduler.
@@ -1681,6 +1681,7 @@
     binder::Status getStalledTransactionInfo(
             int pid, std::optional<gui::StalledTransactionInfo>* outInfo) override;
     binder::Status getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) override;
+    binder::Status notifyShutdown() override;
 
 private:
     static const constexpr bool kUsePermissionCache = true;
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
index b3e9fab..fc496b2 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
@@ -247,7 +247,8 @@
         proto.set_auto_refresh(layer.autoRefresh);
     }
     if (layer.what & layer_state_t::eTrustedOverlayChanged) {
-        proto.set_is_trusted_overlay(layer.isTrustedOverlay);
+        proto.set_is_trusted_overlay(layer.trustedOverlay == gui::TrustedOverlay::ENABLED);
+        // TODO(b/339701674) update protos
     }
     if (layer.what & layer_state_t::eBufferCropChanged) {
         LayerProtoHelper::writeToProto(layer.bufferCrop, proto.mutable_buffer_crop());
@@ -515,7 +516,8 @@
         layer.autoRefresh = proto.auto_refresh();
     }
     if (proto.what() & layer_state_t::eTrustedOverlayChanged) {
-        layer.isTrustedOverlay = proto.is_trusted_overlay();
+        layer.trustedOverlay = proto.is_trusted_overlay() ? gui::TrustedOverlay::ENABLED
+                                                          : gui::TrustedOverlay::UNSET;
     }
     if (proto.what() & layer_state_t::eBufferCropChanged) {
         LayerProtoHelper::readFromProto(proto.buffer_crop(), layer.bufferCrop);
diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp
index 121629f..57b170f 100644
--- a/services/surfaceflinger/common/FlagManager.cpp
+++ b/services/surfaceflinger/common/FlagManager.cpp
@@ -147,6 +147,7 @@
     DUMP_READ_ONLY_FLAG(detached_mirror);
     DUMP_READ_ONLY_FLAG(commit_not_composited);
     DUMP_READ_ONLY_FLAG(local_tonemap_screenshots);
+    DUMP_READ_ONLY_FLAG(override_trusted_overlay);
 
 #undef DUMP_READ_ONLY_FLAG
 #undef DUMP_SERVER_FLAG
@@ -244,6 +245,7 @@
 FLAG_MANAGER_READ_ONLY_FLAG(detached_mirror, "");
 FLAG_MANAGER_READ_ONLY_FLAG(commit_not_composited, "");
 FLAG_MANAGER_READ_ONLY_FLAG(local_tonemap_screenshots, "debug.sf.local_tonemap_screenshots");
+FLAG_MANAGER_READ_ONLY_FLAG(override_trusted_overlay, "");
 
 /// 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 4cf4453..9517ff7 100644
--- a/services/surfaceflinger/common/include/common/FlagManager.h
+++ b/services/surfaceflinger/common/include/common/FlagManager.h
@@ -86,6 +86,7 @@
     bool detached_mirror() const;
     bool commit_not_composited() const;
     bool local_tonemap_screenshots() const;
+    bool override_trusted_overlay() const;
 
 protected:
     // overridden for unit tests
diff --git a/services/surfaceflinger/surfaceflinger_flags_new.aconfig b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
index 5b94f07..02d8819 100644
--- a/services/surfaceflinger/surfaceflinger_flags_new.aconfig
+++ b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
@@ -52,7 +52,7 @@
   metadata {
     purpose: PURPOSE_BUGFIX
   }
-} # deprecate_vsync_sf
+} # detached_mirror
 
 flag {
   name: "frame_rate_category_mrr"
@@ -84,6 +84,17 @@
     is_fixed_read_only: true
 } # local_tonemap_screenshots
 
+ flag {
+  name: "override_trusted_overlay"
+  namespace: "window_surfaces"
+  description: "Allow child to disable trusted overlay set by a parent layer"
+  bug: "339701674"
+  is_fixed_read_only: true
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+} # override_trusted_overlay
+
 flag {
   name: "vrr_bugfix_24q4"
   namespace: "core_graphics"
diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
index 9fd687c..dac9265 100644
--- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
@@ -1132,6 +1132,72 @@
     EXPECT_EQ(received.cookie(), source.cookie());
 }
 
+TEST_F(FrameTimelineTest, traceDisplayFrameNoSkipped) {
+    // setup 2 display frames
+    // DF 1: [22, 30] -> [0, 11]
+    // DF 2: [82, 90] -> SF [5, 16]
+    auto tracingSession = getTracingSessionForTest();
+    tracingSession->StartBlocking();
+    int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
+    int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
+    int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({0, 11, 25});
+    int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({5, 16, 30});
+    auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+
+    int64_t traceCookie = snoopCurrentTraceCookie();
+
+    // set up 1st display frame
+    FrameTimelineInfo ftInfo1;
+    ftInfo1.vsyncId = surfaceFrameToken1;
+    ftInfo1.inputEventId = sInputEventId;
+    auto surfaceFrame1 =
+            mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
+                                                       sLayerNameOne, sLayerNameOne,
+                                                       /*isBuffer*/ true, sGameMode);
+    surfaceFrame1->setAcquireFenceTime(11);
+    mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
+    surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
+    mFrameTimeline->addSurfaceFrame(surfaceFrame1);
+    mFrameTimeline->setSfPresent(30, presentFence1);
+    presentFence1->signalForTest(40);
+
+    // Trigger a flush by finalizing the next DisplayFrame
+    auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+    FrameTimelineInfo ftInfo2;
+    ftInfo2.vsyncId = surfaceFrameToken2;
+    ftInfo2.inputEventId = sInputEventId;
+    auto surfaceFrame2 =
+            mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
+                                                       sLayerNameOne, sLayerNameOne,
+                                                       /*isBuffer*/ true, sGameMode);
+
+    // set up 2nd display frame
+    surfaceFrame2->setAcquireFenceTime(16);
+    mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
+    surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
+    mFrameTimeline->addSurfaceFrame(surfaceFrame2);
+    mFrameTimeline->setSfPresent(90, presentFence2);
+    presentFence2->signalForTest(100);
+
+    // the token of skipped Display Frame
+    auto protoSkippedActualDisplayFrameStart =
+            createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
+                                               FrameTimelineEvent::PRESENT_DROPPED, true, false,
+                                               FrameTimelineEvent::JANK_DROPPED,
+                                               FrameTimelineEvent::SEVERITY_NONE,
+                                               FrameTimelineEvent::PREDICTION_VALID);
+    auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
+
+    // Trigger a flush by finalizing the next DisplayFrame
+    addEmptyDisplayFrame();
+    flushTrace();
+    tracingSession->StopBlocking();
+
+    auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
+    // 8 Valid Display Frames + 8 Valid Surface Frames + no Skipped Display Frames
+    EXPECT_EQ(packets.size(), 16u);
+}
+
 TEST_F(FrameTimelineTest, traceDisplayFrameSkipped) {
     SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::add_sf_skipped_frames_to_trace,
                       true);
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index fd15eef..8b3303c 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -494,14 +494,14 @@
         mLifecycleManager.applyTransactions(transactions);
     }
 
-    void setTrustedOverlay(uint32_t id, bool isTrustedOverlay) {
+    void setTrustedOverlay(uint32_t id, gui::TrustedOverlay trustedOverlay) {
         std::vector<TransactionState> transactions;
         transactions.emplace_back();
         transactions.back().states.push_back({});
 
         transactions.back().states.front().state.what = layer_state_t::eTrustedOverlayChanged;
         transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.isTrustedOverlay = isTrustedOverlay;
+        transactions.back().states.front().state.trustedOverlay = trustedOverlay;
         mLifecycleManager.applyTransactions(transactions);
     }
 
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index 23b6851..bd0accd 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -280,106 +280,13 @@
     transactions.back().states.front().layerId = 1;
     transactions.back().states.front().state.layerId = static_cast<int32_t>(1);
     mLifecycleManager.applyTransactions(transactions);
-    EXPECT_EQ(mLifecycleManager.getGlobalChanges(),
-              RequestedLayerState::Changes::GameMode | RequestedLayerState::Changes::Metadata);
+    EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::GameMode);
     UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
     EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eMetadataChanged);
     EXPECT_EQ(static_cast<int32_t>(getSnapshot(1)->gameMode), 42);
     EXPECT_EQ(static_cast<int32_t>(getSnapshot(11)->gameMode), 42);
 }
 
-TEST_F(LayerSnapshotTest, UpdateMetadata) {
-    std::vector<TransactionState> transactions;
-    transactions.emplace_back();
-    transactions.back().states.push_back({});
-    transactions.back().states.front().state.what = layer_state_t::eMetadataChanged;
-    // This test focuses on metadata used by ARC++ to ensure LayerMetadata is updated correctly,
-    // and not using stale data.
-    transactions.back().states.front().state.metadata = LayerMetadata();
-    transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_UID, 123);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_WINDOW_TYPE, 234);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_TASK_ID, 345);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_MOUSE_CURSOR, 456);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_ACCESSIBILITY_ID, 567);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_PID, 678);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_CALLING_UID, 789);
-
-    transactions.back().states.front().layerId = 1;
-    transactions.back().states.front().state.layerId = static_cast<int32_t>(1);
-
-    mLifecycleManager.applyTransactions(transactions);
-    EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::Metadata);
-
-    // Setting includeMetadata=true to ensure metadata update is applied to LayerSnapshot
-    LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(),
-                                    .layerLifecycleManager = mLifecycleManager,
-                                    .includeMetadata = true,
-                                    .displays = mFrontEndDisplayInfos,
-                                    .globalShadowSettings = globalShadowSettings,
-                                    .supportsBlur = true,
-                                    .supportedLayerGenericMetadata = {},
-                                    .genericLayerMetadataKeyMap = {}};
-    update(mSnapshotBuilder, args);
-
-    EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eMetadataChanged);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_UID, -1), 123);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_WINDOW_TYPE, -1), 234);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_TASK_ID, -1), 345);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_MOUSE_CURSOR, -1), 456);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_ACCESSIBILITY_ID, -1), 567);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_PID, -1), 678);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_CALLING_UID, -1), 789);
-}
-
-TEST_F(LayerSnapshotTest, UpdateMetadataOfHiddenLayers) {
-    hideLayer(1);
-
-    std::vector<TransactionState> transactions;
-    transactions.emplace_back();
-    transactions.back().states.push_back({});
-    transactions.back().states.front().state.what = layer_state_t::eMetadataChanged;
-    // This test focuses on metadata used by ARC++ to ensure LayerMetadata is updated correctly,
-    // and not using stale data.
-    transactions.back().states.front().state.metadata = LayerMetadata();
-    transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_UID, 123);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_WINDOW_TYPE, 234);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_TASK_ID, 345);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_MOUSE_CURSOR, 456);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_ACCESSIBILITY_ID, 567);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_PID, 678);
-    transactions.back().states.front().state.metadata.setInt32(METADATA_CALLING_UID, 789);
-
-    transactions.back().states.front().layerId = 1;
-    transactions.back().states.front().state.layerId = static_cast<int32_t>(1);
-
-    mLifecycleManager.applyTransactions(transactions);
-    EXPECT_EQ(mLifecycleManager.getGlobalChanges(),
-              RequestedLayerState::Changes::Metadata | RequestedLayerState::Changes::Visibility |
-                      RequestedLayerState::Changes::VisibleRegion |
-                      RequestedLayerState::Changes::AffectsChildren);
-
-    // Setting includeMetadata=true to ensure metadata update is applied to LayerSnapshot
-    LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(),
-                                    .layerLifecycleManager = mLifecycleManager,
-                                    .includeMetadata = true,
-                                    .displays = mFrontEndDisplayInfos,
-                                    .globalShadowSettings = globalShadowSettings,
-                                    .supportsBlur = true,
-                                    .supportedLayerGenericMetadata = {},
-                                    .genericLayerMetadataKeyMap = {}};
-    update(mSnapshotBuilder, args);
-
-    EXPECT_EQ(static_cast<int64_t>(getSnapshot(1)->clientChanges),
-              layer_state_t::eMetadataChanged | layer_state_t::eFlagsChanged);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_UID, -1), 123);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_WINDOW_TYPE, -1), 234);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_TASK_ID, -1), 345);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_MOUSE_CURSOR, -1), 456);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_ACCESSIBILITY_ID, -1), 567);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_PID, -1), 678);
-    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_CALLING_UID, -1), 789);
-}
-
 TEST_F(LayerSnapshotTest, NoLayerVoteForParentWithChildVotes) {
     // ROOT
     // ├── 1
@@ -1245,7 +1152,7 @@
 
 TEST_F(LayerSnapshotTest, setTrustedOverlayForNonVisibleInput) {
     hideLayer(1);
-    setTrustedOverlay(1, true);
+    setTrustedOverlay(1, gui::TrustedOverlay::ENABLED);
     Region touch{Rect{0, 0, 1000, 1000}};
     setTouchableRegion(1, touch);
 
@@ -1376,17 +1283,6 @@
     EXPECT_TRUE(foundInputLayer);
 }
 
-TEST_F(LayerSnapshotTest, ForEachSnapshotsWithPredicate) {
-    std::vector<uint32_t> visitedUniqueSequences;
-    mSnapshotBuilder.forEachSnapshot(
-            [&](const std::unique_ptr<frontend::LayerSnapshot>& snapshot) {
-                visitedUniqueSequences.push_back(snapshot->uniqueSequence);
-            },
-            [](const frontend::LayerSnapshot& snapshot) { return snapshot.uniqueSequence == 111; });
-    EXPECT_EQ(visitedUniqueSequences.size(), 1u);
-    EXPECT_EQ(visitedUniqueSequences[0], 111u);
-}
-
 TEST_F(LayerSnapshotTest, canOccludePresentation) {
     setFlags(12, layer_state_t::eCanOccludePresentation, layer_state_t::eCanOccludePresentation);
     LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(),
@@ -1437,4 +1333,85 @@
     EXPECT_EQ(getSnapshot({.id = 111})->geomLayerTransform.ty(), 220);
 }
 
+TEST_F(LayerSnapshotTest, overrideParentTrustedOverlayState) {
+    SET_FLAG_FOR_TEST(flags::override_trusted_overlay, true);
+    hideLayer(1);
+    setTrustedOverlay(1, gui::TrustedOverlay::ENABLED);
+
+    Region touch{Rect{0, 0, 1000, 1000}};
+    setTouchableRegion(1, touch);
+    setTouchableRegion(11, touch);
+    setTouchableRegion(111, touch);
+
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {2});
+    EXPECT_TRUE(getSnapshot(1)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_TRUE(getSnapshot(11)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_TRUE(getSnapshot(111)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+
+    // disable trusted overlay and override parent state
+    setTrustedOverlay(11, gui::TrustedOverlay::DISABLED);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {2});
+    EXPECT_TRUE(getSnapshot(1)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_FALSE(getSnapshot(11)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_FALSE(getSnapshot(111)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+
+    // unset state and go back to default behavior of inheriting
+    // state
+    setTrustedOverlay(11, gui::TrustedOverlay::UNSET);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {2});
+    EXPECT_TRUE(getSnapshot(1)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_TRUE(getSnapshot(11)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_TRUE(getSnapshot(111)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+}
+
+TEST_F(LayerSnapshotTest, doNotOverrideParentTrustedOverlayState) {
+    SET_FLAG_FOR_TEST(flags::override_trusted_overlay, false);
+    hideLayer(1);
+    setTrustedOverlay(1, gui::TrustedOverlay::ENABLED);
+
+    Region touch{Rect{0, 0, 1000, 1000}};
+    setTouchableRegion(1, touch);
+    setTouchableRegion(11, touch);
+    setTouchableRegion(111, touch);
+
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {2});
+    EXPECT_TRUE(getSnapshot(1)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_TRUE(getSnapshot(11)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_TRUE(getSnapshot(111)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+
+    // disable trusted overlay but flag is disabled so this behaves
+    // as UNSET
+    setTrustedOverlay(11, gui::TrustedOverlay::DISABLED);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {2});
+    EXPECT_TRUE(getSnapshot(1)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_TRUE(getSnapshot(11)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_TRUE(getSnapshot(111)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+
+    // unset state and go back to default behavior of inheriting
+    // state
+    setTrustedOverlay(11, gui::TrustedOverlay::UNSET);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {2});
+    EXPECT_TRUE(getSnapshot(1)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_TRUE(getSnapshot(11)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+    EXPECT_TRUE(getSnapshot(111)->inputInfo.inputConfig.test(
+            gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+}
+
 } // namespace android::surfaceflinger::frontend
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 7ea98f5..3f89960 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -964,14 +964,20 @@
 
 PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
     const ProcHook* hook = GetProcHook(pName);
+    PFN_vkVoidFunction drv_func = GetData(device).driver.GetDeviceProcAddr(device, pName);
+
     if (!hook)
-        return GetData(device).driver.GetDeviceProcAddr(device, pName);
+        return drv_func;
 
     if (hook->type != ProcHook::DEVICE) {
         ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
         return nullptr;
     }
 
+    // Don't hook if we don't have a device entry function below for the core function.
+    if (!drv_func && (hook->extension >= ProcHook::EXTENSION_CORE_1_0))
+        return nullptr;
+
     return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
                                                               : nullptr;
 }
diff --git a/vulkan/scripts/driver_generator.py b/vulkan/scripts/driver_generator.py
index 78b550c..48c0ae9 100644
--- a/vulkan/scripts/driver_generator.py
+++ b/vulkan/scripts/driver_generator.py
@@ -239,6 +239,8 @@
       f.write(gencom.indent(2) + gencom.base_ext_name(ext) + ',\n')
 
     f.write('\n')
+    # EXTENSION_CORE_xxx API list must be the last set of enums after the extensions.
+    # This allows to easily identify "a" core function hook
     for version in gencom.version_code_list:
       f.write(gencom.indent(2) + 'EXTENSION_CORE_' + version + ',\n')