Merge "Update call to deprecated Graphite accessor" into main
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 6576ffd..220fef6 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1559,6 +1559,13 @@
                CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
 
     printf("========================================================\n");
+    printf("== Networking Policy\n");
+    printf("========================================================\n");
+
+    RunDumpsys("DUMPSYS NETWORK POLICY", {"netpolicy"}, CommandOptions::WithTimeout(90).Build(),
+               SEC_TO_MSEC(10));
+
+    printf("========================================================\n");
     printf("== Dropbox crashes\n");
     printf("========================================================\n");
 
diff --git a/cmds/installd/otapreopt_script.sh b/cmds/installd/otapreopt_script.sh
index 9384926..28bd793 100644
--- a/cmds/installd/otapreopt_script.sh
+++ b/cmds/installd/otapreopt_script.sh
@@ -50,37 +50,6 @@
   exit 1
 fi
 
-# A source that infinitely emits arbitrary lines.
-# When connected to STDIN of another process, this source keeps STDIN open until
-# the consumer process closes STDIN or this script dies.
-function infinite_source {
-  while echo .; do
-    sleep 1
-  done
-}
-
-PR_DEXOPT_JOB_VERSION="$(pm art pr-dexopt-job --version)"
-if (( $? == 0 )) && (( $PR_DEXOPT_JOB_VERSION >= 2 )); then
-  # Delegate to Pre-reboot Dexopt, a feature of ART Service.
-  # ART Service decides what to do with this request:
-  # - If Pre-reboot Dexopt is disabled or unsupported, the command returns
-  #   non-zero. This is always the case if the current system is Android 14 or
-  #   earlier.
-  # - If Pre-reboot Dexopt is enabled in synchronous mode, the command blocks
-  #   until Pre-reboot Dexopt finishes, and returns zero no matter it succeeds or
-  #   not. This is the default behavior if the current system is Android 15.
-  # - If Pre-reboot Dexopt is enabled in asynchronous mode, the command schedules
-  #   an asynchronous job and returns 0 immediately. The job will then run by the
-  #   job scheduler when the device is idle and charging.
-  if infinite_source | pm art on-ota-staged --slot "$TARGET_SLOT_SUFFIX"; then
-    # Handled by Pre-reboot Dexopt.
-    exit 0
-  fi
-  echo "Pre-reboot Dexopt not enabled. Fall back to otapreopt."
-else
-  echo "Pre-reboot Dexopt is too old. Fall back to otapreopt."
-fi
-
 if [ "$(/system/bin/otapreopt_chroot --version)" != 2 ]; then
   # We require an updated chroot wrapper that reads dexopt commands from stdin.
   # Even if we kept compat with the old binary, the OTA preopt wouldn't work due
diff --git a/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt b/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt
index ff3ae5a..4f293b9 100644
--- a/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt
+++ b/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt
@@ -1,7 +1,5 @@
 package com.android.graphics.bufferstreamsdemoapp
 
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButton
 import androidx.compose.material3.MaterialTheme
@@ -29,10 +27,11 @@
             navigationIcon = {
                 if (canNavigateBack) {
                     IconButton(onClick = navigateUp) {
-                        Icon(
-                                imageVector = Icons.AutoMirrored.Filled.ArrowBack,
-                                contentDescription = stringResource(R.string.back_button)
-                        )
+                        // b/355293776
+                        // Icon(
+                        //     imageVector = Icons.AutoMirrored.Filled.ArrowBack,
+                        //     contentDescription = stringResource(R.string.back_button)
+                        // )
                     }
                 }
             }
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index e6331e7..eeb8f19 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -21,8 +21,11 @@
 
 #include <inttypes.h>
 
+#include <com_android_graphics_libgui_flags.h>
 #include <gui/BufferItem.h>
 #include <gui/BufferItemConsumer.h>
+#include <ui/BufferQueueDefs.h>
+#include <ui/GraphicBuffer.h>
 
 #define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
 // #define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
@@ -87,17 +90,38 @@
 
 status_t BufferItemConsumer::releaseBuffer(const BufferItem &item,
         const sp<Fence>& releaseFence) {
-    status_t err;
+    Mutex::Autolock _l(mMutex);
+    return releaseBufferSlotLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
+}
 
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+status_t BufferItemConsumer::releaseBuffer(const sp<GraphicBuffer>& buffer,
+                                           const sp<Fence>& releaseFence) {
     Mutex::Autolock _l(mMutex);
 
-    err = addReleaseFenceLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
+    if (buffer == nullptr) {
+        return BAD_VALUE;
+    }
+
+    int slotIndex = getSlotForBufferLocked(buffer);
+    if (slotIndex == INVALID_BUFFER_SLOT) {
+        return BAD_VALUE;
+    }
+
+    return releaseBufferSlotLocked(slotIndex, buffer, releaseFence);
+}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
+status_t BufferItemConsumer::releaseBufferSlotLocked(int slotIndex, const sp<GraphicBuffer>& buffer,
+                                                     const sp<Fence>& releaseFence) {
+    status_t err;
+
+    err = addReleaseFenceLocked(slotIndex, buffer, releaseFence);
     if (err != OK) {
         BI_LOGE("Failed to addReleaseFenceLocked");
     }
 
-    err = releaseBufferLocked(item.mSlot, item.mGraphicBuffer, EGL_NO_DISPLAY,
-            EGL_NO_SYNC_KHR);
+    err = releaseBufferLocked(slotIndex, buffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
     if (err != OK && err != IGraphicBufferConsumer::STALE_BUFFER_SLOT) {
         BI_LOGE("Failed to release buffer: %s (%d)",
                 strerror(-err), err);
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index b625c3f..19b9c8b 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -30,9 +30,10 @@
 #include <cutils/atomic.h>
 
 #include <gui/BufferItem.h>
+#include <gui/ConsumerBase.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/SurfaceComposerClient.h>
-#include <gui/ConsumerBase.h>
+#include <ui/BufferQueueDefs.h>
 
 #include <private/gui/ComposerService.h>
 
@@ -40,6 +41,8 @@
 #include <utils/String8.h>
 #include <utils/Trace.h>
 
+#include <com_android_graphics_libgui_flags.h>
+
 // Macros for including the ConsumerBase name in log messages
 #define CB_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
 // #define CB_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
@@ -96,6 +99,35 @@
     abandon();
 }
 
+int ConsumerBase::getSlotForBufferLocked(const sp<GraphicBuffer>& buffer) {
+    if (!buffer) {
+        return BufferQueue::INVALID_BUFFER_SLOT;
+    }
+
+    uint64_t id = buffer->getId();
+    for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) {
+        auto& slot = mSlots[i];
+        if (slot.mGraphicBuffer && slot.mGraphicBuffer->getId() == id) {
+            return i;
+        }
+    }
+
+    return BufferQueue::INVALID_BUFFER_SLOT;
+}
+
+status_t ConsumerBase::detachBufferLocked(int slotIndex) {
+    status_t result = mConsumer->detachBuffer(slotIndex);
+
+    if (result != NO_ERROR) {
+        CB_LOGE("Failed to detach buffer: %d", result);
+        return result;
+    }
+
+    freeBufferLocked(slotIndex);
+
+    return result;
+}
+
 void ConsumerBase::freeBufferLocked(int slotIndex) {
     CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
     mSlots[slotIndex].mGraphicBuffer = nullptr;
@@ -252,16 +284,30 @@
         return NO_INIT;
     }
 
-    status_t result = mConsumer->detachBuffer(slot);
-    if (result != NO_ERROR) {
-        CB_LOGE("Failed to detach buffer: %d", result);
-        return result;
+    return detachBufferLocked(slot);
+}
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+status_t ConsumerBase::detachBuffer(const sp<GraphicBuffer>& buffer) {
+    CB_LOGV("detachBuffer");
+    Mutex::Autolock lock(mMutex);
+
+    if (mAbandoned) {
+        CB_LOGE("detachBuffer: ConsumerBase is abandoned!");
+        return NO_INIT;
+    }
+    if (buffer == nullptr) {
+        return BAD_VALUE;
     }
 
-    freeBufferLocked(slot);
+    int slotIndex = getSlotForBufferLocked(buffer);
+    if (slotIndex == BufferQueue::INVALID_BUFFER_SLOT) {
+        return BAD_VALUE;
+    }
 
-    return result;
+    return detachBufferLocked(slotIndex);
 }
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
 
 status_t ConsumerBase::setDefaultBufferSize(uint32_t width, uint32_t height) {
     Mutex::Autolock _l(mMutex);
diff --git a/libs/gui/include/gui/BufferItemConsumer.h b/libs/gui/include/gui/BufferItemConsumer.h
index a905610..e383a40 100644
--- a/libs/gui/include/gui/BufferItemConsumer.h
+++ b/libs/gui/include/gui/BufferItemConsumer.h
@@ -17,13 +17,15 @@
 #ifndef ANDROID_GUI_BUFFERITEMCONSUMER_H
 #define ANDROID_GUI_BUFFERITEMCONSUMER_H
 
-#include <gui/ConsumerBase.h>
+#include <com_android_graphics_libgui_flags.h>
 #include <gui/BufferQueue.h>
+#include <gui/ConsumerBase.h>
 
 #define ANDROID_GRAPHICS_BUFFERITEMCONSUMER_JNI_ID "mBufferItemConsumer"
 
 namespace android {
 
+class GraphicBuffer;
 class String8;
 
 /**
@@ -85,7 +87,15 @@
     status_t releaseBuffer(const BufferItem &item,
             const sp<Fence>& releaseFence = Fence::NO_FENCE);
 
-   private:
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+    status_t releaseBuffer(const sp<GraphicBuffer>& buffer,
+                           const sp<Fence>& releaseFence = Fence::NO_FENCE);
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
+private:
+    status_t releaseBufferSlotLocked(int slotIndex, const sp<GraphicBuffer>& buffer,
+                                     const sp<Fence>& releaseFence);
+
     void freeBufferLocked(int slotIndex) override;
 
     // mBufferFreedListener is the listener object that will be called when
diff --git a/libs/gui/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h
index 8ff0cd0..a031e66 100644
--- a/libs/gui/include/gui/ConsumerBase.h
+++ b/libs/gui/include/gui/ConsumerBase.h
@@ -17,18 +17,16 @@
 #ifndef ANDROID_GUI_CONSUMERBASE_H
 #define ANDROID_GUI_CONSUMERBASE_H
 
+#include <com_android_graphics_libgui_flags.h>
 #include <gui/BufferQueueDefs.h>
 #include <gui/IConsumerListener.h>
 #include <gui/IGraphicBufferConsumer.h>
 #include <gui/OccupancyTracker.h>
-
 #include <ui/PixelFormat.h>
-
 #include <utils/String8.h>
 #include <utils/Vector.h>
 #include <utils/threads.h>
 
-
 namespace android {
 // ----------------------------------------------------------------------------
 
@@ -81,7 +79,13 @@
     void setFrameAvailableListener(const wp<FrameAvailableListener>& listener);
 
     // See IGraphicBufferConsumer::detachBuffer
-    status_t detachBuffer(int slot);
+    status_t detachBuffer(int slot) __attribute((
+            deprecated("Please use the GraphicBuffer variant--slots are deprecated.")));
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+    // See IGraphicBufferConsumer::detachBuffer
+    status_t detachBuffer(const sp<GraphicBuffer>& buffer);
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
 
     // See IGraphicBufferConsumer::setDefaultBufferSize
     status_t setDefaultBufferSize(uint32_t width, uint32_t height);
@@ -150,6 +154,10 @@
     virtual void onBuffersReleased() override;
     virtual void onSidebandStreamChanged() override;
 
+    virtual int getSlotForBufferLocked(const sp<GraphicBuffer>& buffer);
+
+    virtual status_t detachBufferLocked(int slotIndex);
+
     // freeBufferLocked frees up the given buffer slot.  If the slot has been
     // initialized this will release the reference to the GraphicBuffer in that
     // slot.  Otherwise it has no effect.
diff --git a/libs/gui/tests/BufferItemConsumer_test.cpp b/libs/gui/tests/BufferItemConsumer_test.cpp
index 6880678..7d33f28 100644
--- a/libs/gui/tests/BufferItemConsumer_test.cpp
+++ b/libs/gui/tests/BufferItemConsumer_test.cpp
@@ -17,10 +17,12 @@
 #define LOG_TAG "BufferItemConsumer_test"
 //#define LOG_NDEBUG 0
 
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <gui/BufferItemConsumer.h>
 #include <gui/IProducerListener.h>
 #include <gui/Surface.h>
+#include <ui/GraphicBuffer.h>
 
 namespace android {
 
@@ -42,6 +44,17 @@
         BufferItemConsumerTest* mTest;
     };
 
+    struct TrackingProducerListener : public BnProducerListener {
+        TrackingProducerListener(BufferItemConsumerTest* test) : mTest(test) {}
+
+        virtual void onBufferReleased() override {}
+        virtual bool needsReleaseNotify() override { return true; }
+        virtual void onBuffersDiscarded(const std::vector<int32_t>&) override {}
+        virtual void onBufferDetached(int slot) override { mTest->HandleBufferDetached(slot); }
+
+        BufferItemConsumerTest* mTest;
+    };
+
     void SetUp() override {
         BufferQueue::createBufferQueue(&mProducer, &mConsumer);
         mBIC =
@@ -51,7 +64,7 @@
         mBFL = new BufferFreedListener(this);
         mBIC->setBufferFreedListener(mBFL);
 
-        sp<IProducerListener> producerListener = new StubProducerListener();
+        sp<IProducerListener> producerListener = new TrackingProducerListener(this);
         IGraphicBufferProducer::QueueBufferOutput bufferOutput;
         ASSERT_EQ(NO_ERROR,
                   mProducer->connect(producerListener, NATIVE_WINDOW_API_CPU,
@@ -71,6 +84,13 @@
         ALOGD("HandleBufferFreed, mFreedBufferCount=%d", mFreedBufferCount);
     }
 
+    void HandleBufferDetached(int slot) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mDetachedBufferSlots.push_back(slot);
+        ALOGD("HandleBufferDetached, slot=%d mDetachedBufferSlots-count=%zu", slot,
+              mDetachedBufferSlots.size());
+    }
+
     void DequeueBuffer(int* outSlot) {
         ASSERT_NE(outSlot, nullptr);
 
@@ -120,6 +140,7 @@
 
     std::mutex mMutex;
     int mFreedBufferCount{0};
+    std::vector<int> mDetachedBufferSlots = {};
 
     sp<BufferItemConsumer> mBIC;
     sp<BufferFreedListener> mBFL;
@@ -203,4 +224,19 @@
     ASSERT_EQ(1, GetFreedBufferCount());
 }
 
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+// Test that delete BufferItemConsumer triggers onBufferFreed.
+TEST_F(BufferItemConsumerTest, DetachBufferWithBuffer) {
+    int slot;
+    // Let buffer go through the cycle at least once.
+    DequeueBuffer(&slot);
+    QueueBuffer(slot);
+    AcquireBuffer(&slot);
+
+    sp<GraphicBuffer> buffer = mBuffers[slot];
+    EXPECT_EQ(OK, mBIC->detachBuffer(buffer));
+    EXPECT_THAT(mDetachedBufferSlots, testing::ElementsAre(slot));
+}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
 }  // namespace android
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index 4e09381..47fd700 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -320,11 +320,8 @@
 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;
-    }
+    snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE) ? requested.gameMode
+                                                                        : parentSnapshot.gameMode;
     updateMetadata(snapshot, requested, args);
     if (args.includeMetadata) {
         snapshot.layerMetadata = parentSnapshot.layerMetadata;
@@ -780,7 +777,8 @@
         }
         if (forceUpdate ||
             (args.includeMetadata &&
-             snapshot.changes.test(RequestedLayerState::Changes::Metadata))) {
+             snapshot.changes.any(RequestedLayerState::Changes::Metadata |
+                                  RequestedLayerState::Changes::Geometry))) {
             updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot);
         }
         return;
@@ -848,7 +846,9 @@
         }
     }
 
-    if (forceUpdate || snapshot.changes.test(RequestedLayerState::Changes::Metadata)) {
+    if (forceUpdate ||
+        snapshot.changes.any(RequestedLayerState::Changes::Metadata |
+                             RequestedLayerState::Changes::Hierarchy)) {
         updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot);
     }
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 0eb6cc3..1258509 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1314,7 +1314,7 @@
 }
 
 void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info,
-                                                      nsecs_t postTime) {
+                                                      nsecs_t postTime, gui::GameMode gameMode) {
     mDrawingState.postTime = postTime;
 
     // Check if one of the bufferlessSurfaceFramesTX contains the same vsyncId. This can happen if
@@ -1330,14 +1330,15 @@
         mDrawingState.bufferSurfaceFrameTX->setActualQueueTime(postTime);
     } else {
         mDrawingState.bufferSurfaceFrameTX =
-                createSurfaceFrameForBuffer(info, postTime, mTransactionName);
+                createSurfaceFrameForBuffer(info, postTime, mTransactionName, gameMode);
     }
 
-    setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName);
+    setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode);
 }
 
 void Layer::setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info,
-                                                          nsecs_t postTime) {
+                                                          nsecs_t postTime,
+                                                          gui::GameMode gameMode) {
     mDrawingState.frameTimelineInfo = info;
     mDrawingState.postTime = postTime;
     mDrawingState.modified = true;
@@ -1356,17 +1357,17 @@
     // targeting different vsyncs).
     auto it = mDrawingState.bufferlessSurfaceFramesTX.find(info.vsyncId);
     if (it == mDrawingState.bufferlessSurfaceFramesTX.end()) {
-        auto surfaceFrame = createSurfaceFrameForTransaction(info, postTime);
+        auto surfaceFrame = createSurfaceFrameForTransaction(info, postTime, gameMode);
         mDrawingState.bufferlessSurfaceFramesTX[info.vsyncId] = surfaceFrame;
     } else {
         if (it->second->getPresentState() == PresentState::Presented) {
             // If the SurfaceFrame was already presented, its safe to overwrite it since it must
             // have been from previous vsync.
-            it->second = createSurfaceFrameForTransaction(info, postTime);
+            it->second = createSurfaceFrameForTransaction(info, postTime, gameMode);
         }
     }
 
-    setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName);
+    setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode);
 }
 
 void Layer::addSurfaceFrameDroppedForBuffer(
@@ -1386,12 +1387,12 @@
 }
 
 std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForTransaction(
-        const FrameTimelineInfo& info, nsecs_t postTime) {
+        const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode) {
     auto surfaceFrame =
             mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid,
                                                                  getSequence(), mName,
                                                                  mTransactionName,
-                                                                 /*isBuffer*/ false, getGameMode());
+                                                                 /*isBuffer*/ false, gameMode);
     surfaceFrame->setActualStartTime(info.startTimeNanos);
     // For Transactions, the post time is considered to be both queue and acquire fence time.
     surfaceFrame->setActualQueueTime(postTime);
@@ -1404,11 +1405,12 @@
 }
 
 std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer(
-        const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName) {
+        const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName,
+        gui::GameMode gameMode) {
     auto surfaceFrame =
             mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid,
                                                                  getSequence(), mName, debugName,
-                                                                 /*isBuffer*/ true, getGameMode());
+                                                                 /*isBuffer*/ true, gameMode);
     surfaceFrame->setActualStartTime(info.startTimeNanos);
     // For buffers, acquire fence time will set during latch.
     surfaceFrame->setActualQueueTime(queueTime);
@@ -1420,7 +1422,7 @@
 }
 
 void Layer::setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime,
-                                                  std::string debugName) {
+                                                  std::string debugName, gui::GameMode gameMode) {
     if (info.skippedFrameVsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) {
         return;
     }
@@ -1432,7 +1434,7 @@
             mFlinger->mFrameTimeline->createSurfaceFrameForToken(skippedFrameTimelineInfo,
                                                                  mOwnerPid, mOwnerUid,
                                                                  getSequence(), mName, debugName,
-                                                                 /*isBuffer*/ false, getGameMode());
+                                                                 /*isBuffer*/ false, gameMode);
     surfaceFrame->setActualStartTime(skippedFrameTimelineInfo.skippedFrameStartTimeNanos);
     // For Transactions, the post time is considered to be both queue and acquire fence time.
     surfaceFrame->setActualQueueTime(postTime);
@@ -1671,25 +1673,12 @@
     return count;
 }
 
-void Layer::setGameModeForTree(GameMode gameMode) {
-    const auto& currentState = getDrawingState();
-    if (currentState.metadata.has(gui::METADATA_GAME_MODE)) {
-        gameMode =
-                static_cast<GameMode>(currentState.metadata.getInt32(gui::METADATA_GAME_MODE, 0));
-    }
-    setGameMode(gameMode);
-    for (const sp<Layer>& child : mCurrentChildren) {
-        child->setGameModeForTree(gameMode);
-    }
-}
-
 void Layer::addChild(const sp<Layer>& layer) {
     mFlinger->mSomeChildrenChanged = true;
     setTransactionFlags(eTransactionNeeded);
 
     mCurrentChildren.add(layer);
     layer->setParent(sp<Layer>::fromExisting(this));
-    layer->setGameModeForTree(mGameMode);
     updateTreeHasFrameRateVote();
 }
 
@@ -1701,7 +1690,6 @@
     const auto removeResult = mCurrentChildren.remove(layer);
 
     updateTreeHasFrameRateVote();
-    layer->setGameModeForTree(GameMode::Unsupported);
     layer->updateTreeHasFrameRateVote();
 
     return removeResult;
@@ -3082,7 +3070,7 @@
 
 bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer,
                       const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime,
-                      bool isAutoTimestamp, const FrameTimelineInfo& info) {
+                      bool isAutoTimestamp, const FrameTimelineInfo& info, gui::GameMode gameMode) {
     SFTRACE_FORMAT("setBuffer %s - hasBuffer=%s", getDebugName(), (buffer ? "true" : "false"));
 
     const bool frameNumberChanged =
@@ -3108,12 +3096,12 @@
         resetDrawingStateBufferInfo();
         setTransactionFlags(eTransactionNeeded);
         mDrawingState.bufferSurfaceFrameTX = nullptr;
-        setFrameTimelineVsyncForBufferlessTransaction(info, postTime);
+        setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode);
         return true;
     } else {
         // release sideband stream if it exists and a non null buffer is being set
         if (mDrawingState.sidebandStream != nullptr) {
-            setSidebandStream(nullptr, info, postTime);
+            setSidebandStream(nullptr, info, postTime, gameMode);
         }
     }
 
@@ -3152,9 +3140,9 @@
 
     const int32_t layerId = getSequence();
     mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(),
-                                      mOwnerUid, postTime, getGameMode());
+                                      mOwnerUid, postTime, gameMode);
 
-    setFrameTimelineVsyncForBufferTransaction(info, postTime);
+    setFrameTimelineVsyncForBufferTransaction(info, postTime, gameMode);
 
     if (bufferData.dequeueTime > 0) {
         const uint64_t bufferId = mDrawingState.buffer->getId();
@@ -3309,7 +3297,7 @@
 }
 
 bool Layer::setSidebandStream(const sp<NativeHandle>& sidebandStream, const FrameTimelineInfo& info,
-                              nsecs_t postTime) {
+                              nsecs_t postTime, gui::GameMode gameMode) {
     if (mDrawingState.sidebandStream == sidebandStream) return false;
 
     if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) {
@@ -3324,7 +3312,7 @@
         releasePreviousBuffer();
         resetDrawingStateBufferInfo();
         mDrawingState.bufferSurfaceFrameTX = nullptr;
-        setFrameTimelineVsyncForBufferlessTransaction(info, postTime);
+        setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode);
     }
     setTransactionFlags(eTransactionNeeded);
     if (!mSidebandStreamChanged.exchange(true)) {
@@ -3982,7 +3970,8 @@
 void Layer::onCompositionPresented(const DisplayDevice* display,
                                    const std::shared_ptr<FenceTime>& glDoneFence,
                                    const std::shared_ptr<FenceTime>& presentFence,
-                                   const CompositorTiming& compositorTiming) {
+                                   const CompositorTiming& compositorTiming,
+                                   gui::GameMode gameMode) {
     // mFrameLatencyNeeded is true when a new frame was latched for the
     // composition.
     if (!mBufferInfo.mFrameLatencyNeeded) return;
@@ -4029,7 +4018,6 @@
                 mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
 
         const auto vote = frameRateToSetFrameRateVotePayload(getFrameRateForLayerTree());
-        const auto gameMode = getGameMode();
 
         if (presentFence->isValid()) {
             mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence,
@@ -4313,38 +4301,6 @@
     }
 }
 
-void Layer::updateMetadataSnapshot(const LayerMetadata& parentMetadata) {
-    mSnapshot->layerMetadata = parentMetadata;
-    mSnapshot->layerMetadata.merge(mDrawingState.metadata);
-    for (const sp<Layer>& child : mDrawingChildren) {
-        child->updateMetadataSnapshot(mSnapshot->layerMetadata);
-    }
-}
-
-void Layer::updateRelativeMetadataSnapshot(const LayerMetadata& relativeLayerMetadata,
-                                           std::unordered_set<Layer*>& visited) {
-    if (visited.find(this) != visited.end()) {
-        ALOGW("Cycle containing layer %s detected in z-order relatives", getDebugName());
-        return;
-    }
-    visited.insert(this);
-
-    mSnapshot->relativeLayerMetadata = relativeLayerMetadata;
-
-    if (mDrawingState.zOrderRelatives.empty()) {
-        return;
-    }
-    LayerMetadata childRelativeLayerMetadata = mSnapshot->relativeLayerMetadata;
-    childRelativeLayerMetadata.merge(mSnapshot->layerMetadata);
-    for (wp<Layer> weakRelative : mDrawingState.zOrderRelatives) {
-        sp<Layer> relative = weakRelative.promote();
-        if (!relative) {
-            continue;
-        }
-        relative->updateRelativeMetadataSnapshot(childRelativeLayerMetadata, visited);
-    }
-}
-
 bool Layer::setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds,
                                        TrustedPresentationListener const& listener) {
     bool hadTrustedPresentationListener = hasTrustedPresentationListener();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 52f169e..c838b97 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -312,7 +312,7 @@
     bool setBuffer(std::shared_ptr<renderengine::ExternalTexture>& /* buffer */,
                    const BufferData& /* bufferData */, nsecs_t /* postTime */,
                    nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/,
-                   const FrameTimelineInfo& /*info*/);
+                   const FrameTimelineInfo& /*info*/, gui::GameMode gameMode);
     void setDesiredPresentTime(nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/);
     bool setDataspace(ui::Dataspace /*dataspace*/);
     bool setExtendedRangeBrightness(float currentBufferRatio, float desiredRatio);
@@ -322,7 +322,8 @@
     bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/);
     bool setApi(int32_t /*api*/);
     bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/,
-                           const FrameTimelineInfo& /* info*/, nsecs_t /* postTime */);
+                           const FrameTimelineInfo& /* info*/, nsecs_t /* postTime */,
+                           gui::GameMode gameMode);
     bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& /*handles*/,
                                           bool willPresent);
     virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace)
@@ -439,7 +440,7 @@
     void onCompositionPresented(const DisplayDevice*,
                                 const std::shared_ptr<FenceTime>& /*glDoneFence*/,
                                 const std::shared_ptr<FenceTime>& /*presentFence*/,
-                                const CompositorTiming&);
+                                const CompositorTiming&, gui::GameMode gameMode);
 
     // If a buffer was replaced this frame, release the former buffer
     void releasePendingBuffer(nsecs_t /*dequeueReadyTime*/);
@@ -794,9 +795,10 @@
     bool setFrameRateSelectionStrategy(FrameRateSelectionStrategy);
 
     virtual void setFrameTimelineInfoForBuffer(const FrameTimelineInfo& /*info*/) {}
-    void setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime);
+    void setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime,
+                                                   gui::GameMode gameMode);
     void setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info,
-                                                       nsecs_t postTime);
+                                                       nsecs_t postTime, gui::GameMode gameMode);
 
     void addSurfaceFrameDroppedForBuffer(std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame,
                                          nsecs_t dropTime);
@@ -805,11 +807,12 @@
             nsecs_t currentLatchTime);
 
     std::shared_ptr<frametimeline::SurfaceFrame> createSurfaceFrameForTransaction(
-            const FrameTimelineInfo& info, nsecs_t postTime);
+            const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode);
     std::shared_ptr<frametimeline::SurfaceFrame> createSurfaceFrameForBuffer(
-            const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName);
+            const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName,
+            gui::GameMode gameMode);
     void setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime,
-                                               std::string debugName);
+                                               std::string debugName, gui::GameMode gameMode);
 
     bool setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds,
                                     TrustedPresentationListener const& listener);
@@ -832,13 +835,6 @@
      */
     bool hasInputInfo() const;
 
-    // Sets the gui::GameMode for the tree rooted at this layer. A layer in the tree inherits this
-    // gui::GameMode unless it (or an ancestor) has GAME_MODE_METADATA.
-    void setGameModeForTree(gui::GameMode);
-
-    void setGameMode(gui::GameMode gameMode) { mGameMode = gameMode; }
-    gui::GameMode getGameMode() const { return mGameMode; }
-
     virtual uid_t getOwnerUid() const { return mOwnerUid; }
 
     pid_t getOwnerPid() { return mOwnerPid; }
@@ -899,9 +895,6 @@
     // CompositionEngine to create a single path for composing layers.
     void updateSnapshot(bool updateGeometry);
     void updateChildrenSnapshots(bool updateGeometry);
-    void updateMetadataSnapshot(const LayerMetadata& parentMetadata);
-    void updateRelativeMetadataSnapshot(const LayerMetadata& relativeLayerMetadata,
-                                        std::unordered_set<Layer*>& visited);
     sp<Layer> getClonedFrom() const {
         return mClonedFrom != nullptr ? mClonedFrom.promote() : nullptr;
     }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ed2ad7d..18d5bd5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2521,7 +2521,9 @@
         it->second->latchBufferImpl(unused, latchTime, bgColorOnly);
         newDataLatched = true;
 
-        mLayersWithQueuedFrames.emplace(it->second);
+        frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(it->second->sequence);
+        gui::GameMode gameMode = (snapshot) ? snapshot->gameMode : gui::GameMode::Unsupported;
+        mLayersWithQueuedFrames.emplace(it->second, gameMode);
         mLayersIdsWithQueuedFrames.emplace(it->second->sequence);
     }
 
@@ -2750,16 +2752,12 @@
 
     const bool updateTaskMetadata = mCompositionEngine->getFeatureFlags().test(
             compositionengine::Feature::kSnapshotLayerMetadata);
-    if (updateTaskMetadata && (mVisibleRegionsDirty || mLayerMetadataSnapshotNeeded)) {
-        updateLayerMetadataSnapshot();
-        mLayerMetadataSnapshotNeeded = false;
-    }
 
     refreshArgs.bufferIdsToUncache = std::move(mBufferIdsToUncache);
 
     if (!FlagManager::getInstance().ce_fence_promise()) {
         refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
-        for (auto& layer : mLayersWithQueuedFrames) {
+        for (auto& [layer, _] : mLayersWithQueuedFrames) {
             if (const auto& layerFE = layer->getCompositionEngineLayerFE())
                 refreshArgs.layersWithQueuedFrames.push_back(layerFE);
         }
@@ -2835,7 +2833,7 @@
         }
 
         refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
-        for (auto& layer : mLayersWithQueuedFrames) {
+        for (auto& [layer, _] : mLayersWithQueuedFrames) {
             if (const auto& layerFE = layer->getCompositionEngineLayerFE()) {
                 refreshArgs.layersWithQueuedFrames.push_back(layerFE);
                 // Some layers are not displayed and do not yet have a future release fence
@@ -3141,10 +3139,10 @@
     }
     mLayersWithBuffersRemoved.clear();
 
-    for (const auto& layer: mLayersWithQueuedFrames) {
+    for (const auto& [layer, gameMode] : mLayersWithQueuedFrames) {
         layer->onCompositionPresented(pacesetterDisplay.get(),
                                       pacesetterGpuCompositionDoneFenceTime,
-                                      pacesetterPresentFenceTime, compositorTiming);
+                                      pacesetterPresentFenceTime, compositorTiming, gameMode);
         layer->releasePendingBuffer(presentTime.ns());
     }
 
@@ -5191,6 +5189,17 @@
                     sp<CallbackHandle>::make(listener, callbackIds, s.surface));
         }
     }
+
+    frontend::LayerSnapshot* snapshot = nullptr;
+    gui::GameMode gameMode = gui::GameMode::Unsupported;
+    if (what & (layer_state_t::eSidebandStreamChanged | layer_state_t::eBufferChanged) ||
+        frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
+        snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence);
+        if (snapshot) {
+            gameMode = snapshot->gameMode;
+        }
+    }
+
     // TODO(b/238781169) remove after screenshot refactor, currently screenshots
     // requires to read drawing state from binder thread. So we need to fix that
     // before removing this.
@@ -5205,7 +5214,7 @@
         if (layer->setCrop(s.crop)) flags |= eTraversalNeeded;
     }
     if (what & layer_state_t::eSidebandStreamChanged) {
-        if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime))
+        if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime, gameMode))
             flags |= eTraversalNeeded;
     }
     if (what & layer_state_t::eDataspaceChanged) {
@@ -5223,18 +5232,17 @@
     }
     if (what & layer_state_t::eBufferChanged) {
         std::optional<ui::Transform::RotationFlags> transformHint = std::nullopt;
-        frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence);
         if (snapshot) {
             transformHint = snapshot->transformHint;
         }
         layer->setTransformHint(transformHint);
         if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime,
-                             desiredPresentTime, isAutoTimestamp, frameTimelineInfo)) {
+                             desiredPresentTime, isAutoTimestamp, frameTimelineInfo, gameMode)) {
             flags |= eTraversalNeeded;
         }
-        mLayersWithQueuedFrames.emplace(layer);
+        mLayersWithQueuedFrames.emplace(layer, gameMode);
     } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
-        layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime);
+        layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime, gameMode);
     }
 
     if ((what & layer_state_t::eBufferChanged) == 0) {
@@ -8486,31 +8494,6 @@
     return nullptr;
 }
 
-void SurfaceFlinger::updateLayerMetadataSnapshot() {
-    LayerMetadata parentMetadata;
-    for (const auto& layer : mDrawingState.layersSortedByZ) {
-        layer->updateMetadataSnapshot(parentMetadata);
-    }
-
-    std::unordered_set<Layer*> visited;
-    mDrawingState.traverse([&visited](Layer* layer) {
-        if (visited.find(layer) != visited.end()) {
-            return;
-        }
-
-        // If the layer isRelativeOf, then either it's relative metadata will be set
-        // recursively when updateRelativeMetadataSnapshot is called on its relative parent or
-        // it's relative parent has been deleted. Clear the layer's relativeLayerMetadata to ensure
-        // that layers with deleted relative parents don't hold stale relativeLayerMetadata.
-        if (layer->getDrawingState().isRelativeOf) {
-            layer->editLayerSnapshot()->relativeLayerMetadata = {};
-            return;
-        }
-
-        layer->updateRelativeMetadataSnapshot({}, visited);
-    });
-}
-
 void SurfaceFlinger::moveSnapshotsFromCompositionArgs(
         compositionengine::CompositionRefreshArgs& refreshArgs,
         const std::vector<std::pair<Layer*, LayerFE*>>& layers) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index d15fe6f..9a1ad03 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -768,7 +768,6 @@
             REQUIRES(mStateLock, kMainThreadContext);
     void doCommitTransactions() REQUIRES(mStateLock);
 
-    void updateLayerMetadataSnapshot();
     std::vector<std::pair<Layer*, LayerFE*>> moveSnapshotsToCompositionArgs(
             compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly)
             REQUIRES(kMainThreadContext);
@@ -1275,13 +1274,17 @@
     bool mForceTransactionDisplayChange = false;
     bool mUpdateAttachedChoreographer = false;
 
-    // Set if LayerMetadata has changed since the last LayerMetadata snapshot.
-    bool mLayerMetadataSnapshotNeeded = false;
+    struct LayerIntHash {
+        size_t operator()(const std::pair<sp<Layer>, gui::GameMode>& k) const {
+            return std::hash<Layer*>()(k.first.get()) ^
+                    std::hash<int32_t>()(static_cast<int32_t>(k.second));
+        }
+    };
 
     // TODO(b/238781169) validate these on composition
     // Tracks layers that have pending frames which are candidates for being
     // latched.
-    std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithQueuedFrames;
+    std::unordered_set<std::pair<sp<Layer>, gui::GameMode>, LayerIntHash> mLayersWithQueuedFrames;
     std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithBuffersRemoved;
     std::unordered_set<uint32_t> mLayersIdsWithQueuedFrames;
 
diff --git a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h
index 2e5913b..8b9d14b 100644
--- a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h
+++ b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h
@@ -472,6 +472,18 @@
         mLifecycleManager.applyTransactions(transactions);
     }
 
+    void setGameMode(uint32_t id, gui::GameMode gameMode) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+        transactions.back().states.front().state.what = layer_state_t::eMetadataChanged;
+        transactions.back().states.front().state.metadata = LayerMetadata();
+        transactions.back().states.front().state.metadata.setInt32(METADATA_GAME_MODE,
+                                                                   static_cast<int32_t>(gameMode));
+        transactions.back().states.front().layerId = id;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
 private:
     LayerLifecycleManager& mLifecycleManager;
 };
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 5669819..d9d239d 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -83,7 +83,6 @@
         "FrameRateSelectionPriorityTest.cpp",
         "FrameRateSelectionStrategyTest.cpp",
         "FrameTimelineTest.cpp",
-        "GameModeTest.cpp",
         "HWComposerTest.cpp",
         "JankTrackerTest.cpp",
         "OneShotTimerTest.cpp",
@@ -116,7 +115,6 @@
         "SurfaceFlinger_SetDisplayStateTest.cpp",
         "SurfaceFlinger_SetPowerModeInternalTest.cpp",
         "SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp",
-        "SurfaceFlinger_UpdateLayerMetadataSnapshotTest.cpp",
         "SchedulerTest.cpp",
         "SetFrameRateTest.cpp",
         "RefreshRateSelectorTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/GameModeTest.cpp b/services/surfaceflinger/tests/unittests/GameModeTest.cpp
deleted file mode 100644
index 1b5c6e7..0000000
--- a/services/surfaceflinger/tests/unittests/GameModeTest.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-#undef LOG_TAG
-#define LOG_TAG "LibSurfaceFlingerUnittests"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <gui/LayerMetadata.h>
-#include <gui/SurfaceComposerClient.h>
-#include <log/log.h>
-
-#include "TestableSurfaceFlinger.h"
-#include "mock/DisplayHardware/MockComposer.h"
-
-namespace android {
-
-using testing::_;
-using testing::Mock;
-using testing::Return;
-
-using gui::GameMode;
-using gui::LayerMetadata;
-
-class GameModeTest : public testing::Test {
-public:
-    GameModeTest() {
-        const ::testing::TestInfo* const test_info =
-                ::testing::UnitTest::GetInstance()->current_test_info();
-        ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
-        mFlinger.setupMockScheduler();
-        setupComposer();
-    }
-
-    ~GameModeTest() {
-        const ::testing::TestInfo* const test_info =
-                ::testing::UnitTest::GetInstance()->current_test_info();
-        ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
-    }
-
-    sp<Layer> createLayer() {
-        sp<Client> client;
-        LayerCreationArgs args(mFlinger.flinger(), client, "layer", 0, LayerMetadata());
-        return sp<Layer>::make(args);
-    }
-
-    void setupComposer() {
-        mComposer = new Hwc2::mock::Composer();
-        mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
-
-        Mock::VerifyAndClear(mComposer);
-    }
-
-    // Mocks the behavior of applying a transaction from WMShell
-    void setGameModeMetadata(sp<Layer> layer, GameMode gameMode) {
-        mLayerMetadata.setInt32(gui::METADATA_GAME_MODE, static_cast<int32_t>(gameMode));
-        layer->setMetadata(mLayerMetadata);
-        layer->setGameModeForTree(gameMode);
-    }
-
-    TestableSurfaceFlinger mFlinger;
-    Hwc2::mock::Composer* mComposer = nullptr;
-    client_cache_t mClientCache;
-    LayerMetadata mLayerMetadata;
-};
-
-TEST_F(GameModeTest, SetGameModeSetsForAllCurrentChildren) {
-    sp<Layer> rootLayer = createLayer();
-    sp<Layer> childLayer1 = createLayer();
-    sp<Layer> childLayer2 = createLayer();
-    rootLayer->addChild(childLayer1);
-    rootLayer->addChild(childLayer2);
-    rootLayer->setGameModeForTree(GameMode::Performance);
-
-    EXPECT_EQ(rootLayer->getGameMode(), GameMode::Performance);
-    EXPECT_EQ(childLayer1->getGameMode(), GameMode::Performance);
-    EXPECT_EQ(childLayer2->getGameMode(), GameMode::Performance);
-}
-
-TEST_F(GameModeTest, AddChildAppliesGameModeFromParent) {
-    sp<Layer> rootLayer = createLayer();
-    sp<Layer> childLayer = createLayer();
-    rootLayer->setGameModeForTree(GameMode::Performance);
-    rootLayer->addChild(childLayer);
-
-    EXPECT_EQ(rootLayer->getGameMode(), GameMode::Performance);
-    EXPECT_EQ(childLayer->getGameMode(), GameMode::Performance);
-}
-
-TEST_F(GameModeTest, RemoveChildResetsGameMode) {
-    sp<Layer> rootLayer = createLayer();
-    sp<Layer> childLayer = createLayer();
-    rootLayer->setGameModeForTree(GameMode::Performance);
-    rootLayer->addChild(childLayer);
-
-    EXPECT_EQ(rootLayer->getGameMode(), GameMode::Performance);
-    EXPECT_EQ(childLayer->getGameMode(), GameMode::Performance);
-
-    rootLayer->removeChild(childLayer);
-    EXPECT_EQ(childLayer->getGameMode(), GameMode::Unsupported);
-}
-
-TEST_F(GameModeTest, ReparentingDoesNotOverrideMetadata) {
-    sp<Layer> rootLayer = createLayer();
-    sp<Layer> childLayer1 = createLayer();
-    sp<Layer> childLayer2 = createLayer();
-    rootLayer->setGameModeForTree(GameMode::Standard);
-    rootLayer->addChild(childLayer1);
-
-    setGameModeMetadata(childLayer2, GameMode::Performance);
-    rootLayer->addChild(childLayer2);
-
-    EXPECT_EQ(rootLayer->getGameMode(), GameMode::Standard);
-    EXPECT_EQ(childLayer1->getGameMode(), GameMode::Standard);
-    EXPECT_EQ(childLayer2->getGameMode(), GameMode::Performance);
-
-    rootLayer->removeChild(childLayer2);
-    EXPECT_EQ(childLayer2->getGameMode(), GameMode::Performance);
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index 06319f3..2bb864a 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -281,22 +281,40 @@
     EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eColorChanged);
 }
 
-TEST_F(LayerSnapshotTest, GameMode) {
-    std::vector<TransactionState> transactions;
-    transactions.emplace_back();
-    transactions.back().states.push_back({});
-    transactions.back().states.front().state.what = layer_state_t::eMetadataChanged;
-    transactions.back().states.front().state.metadata = LayerMetadata();
-    transactions.back().states.front().state.metadata.setInt32(METADATA_GAME_MODE, 42);
-    transactions.back().states.front().layerId = 1;
-    transactions.back().states.front().state.layerId = static_cast<int32_t>(1);
-    mLifecycleManager.applyTransactions(transactions);
+TEST_F(LayerSnapshotTest, ChildrenInheritGameMode) {
+    setGameMode(1, gui::GameMode::Performance);
     EXPECT_EQ(mLifecycleManager.getGlobalChanges(),
               RequestedLayerState::Changes::GameMode | RequestedLayerState::Changes::Metadata);
     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);
+    EXPECT_EQ(getSnapshot(1)->gameMode, gui::GameMode::Performance);
+    EXPECT_EQ(getSnapshot(11)->gameMode, gui::GameMode::Performance);
+}
+
+TEST_F(LayerSnapshotTest, ChildrenCanOverrideGameMode) {
+    setGameMode(1, gui::GameMode::Performance);
+    setGameMode(11, gui::GameMode::Battery);
+    EXPECT_EQ(mLifecycleManager.getGlobalChanges(),
+              RequestedLayerState::Changes::GameMode | RequestedLayerState::Changes::Metadata);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eMetadataChanged);
+    EXPECT_EQ(getSnapshot(1)->gameMode, gui::GameMode::Performance);
+    EXPECT_EQ(getSnapshot(11)->gameMode, gui::GameMode::Battery);
+}
+
+TEST_F(LayerSnapshotTest, ReparentingUpdatesGameMode) {
+    setGameMode(1, gui::GameMode::Performance);
+    EXPECT_EQ(mLifecycleManager.getGlobalChanges(),
+              RequestedLayerState::Changes::GameMode | RequestedLayerState::Changes::Metadata);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eMetadataChanged);
+    EXPECT_EQ(getSnapshot(1)->gameMode, gui::GameMode::Performance);
+    EXPECT_EQ(getSnapshot(2)->gameMode, gui::GameMode::Unsupported);
+
+    reparentLayer(2, 1);
+    setZ(2, 2);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_EQ(getSnapshot(2)->gameMode, gui::GameMode::Performance);
 }
 
 TEST_F(LayerSnapshotTest, UpdateMetadata) {
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_UpdateLayerMetadataSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_UpdateLayerMetadataSnapshotTest.cpp
deleted file mode 100644
index 0e5f1ea..0000000
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_UpdateLayerMetadataSnapshotTest.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <gui/LayerMetadata.h>
-
-#include "TestableSurfaceFlinger.h"
-
-namespace android {
-
-using testing::_;
-using testing::Return;
-
-class SurfaceFlingerUpdateLayerMetadataSnapshotTest : public testing::Test {
-public:
-    SurfaceFlingerUpdateLayerMetadataSnapshotTest() { mFlinger.setupMockScheduler(); }
-
-protected:
-    sp<Layer> createLayer(const char* name, LayerMetadata& inOutlayerMetadata) {
-        LayerCreationArgs args =
-                LayerCreationArgs{mFlinger.flinger(), nullptr, name, 0, inOutlayerMetadata};
-        inOutlayerMetadata = args.metadata;
-        return sp<Layer>::make(args);
-    }
-
-    TestableSurfaceFlinger mFlinger;
-};
-
-class LayerMetadataBuilder {
-public:
-    LayerMetadataBuilder(LayerMetadata layerMetadata = {}) : mLayerMetadata(layerMetadata) {}
-
-    LayerMetadataBuilder& setInt32(uint32_t key, int32_t value) {
-        mLayerMetadata.setInt32(key, value);
-        return *this;
-    }
-
-    LayerMetadata build() { return mLayerMetadata; }
-
-private:
-    LayerMetadata mLayerMetadata;
-};
-
-bool operator==(const LayerMetadata& lhs, const LayerMetadata& rhs) {
-    return lhs.mMap == rhs.mMap;
-}
-
-std::ostream& operator<<(std::ostream& stream, const LayerMetadata& layerMetadata) {
-    stream << "LayerMetadata{";
-    for (auto it = layerMetadata.mMap.cbegin(); it != layerMetadata.mMap.cend(); it++) {
-        if (it != layerMetadata.mMap.cbegin()) {
-            stream << ", ";
-        }
-        stream << layerMetadata.itemToString(it->first, ":");
-    }
-    return stream << "}";
-}
-
-// Test that the snapshot's layer metadata is set.
-TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, updatesSnapshotMetadata) {
-    auto layerMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 1).build();
-    auto layer = createLayer("layer", layerMetadata);
-    mFlinger.mutableDrawingState().layersSortedByZ.add(layer);
-
-    mFlinger.updateLayerMetadataSnapshot();
-
-    EXPECT_EQ(layer->getLayerSnapshot()->layerMetadata, layerMetadata);
-}
-
-// Test that snapshot layer metadata is set by merging the child's metadata on top of its
-// parent's metadata.
-TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, mergesSnapshotMetadata) {
-    auto layerAMetadata = LayerMetadataBuilder()
-                                  .setInt32(METADATA_OWNER_UID, 1)
-                                  .setInt32(METADATA_TASK_ID, 2)
-                                  .build();
-    auto layerA = createLayer("parent", layerAMetadata);
-    auto layerBMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 3).build();
-    auto layerB = createLayer("child", layerBMetadata);
-    layerA->addChild(layerB);
-    layerA->commitChildList();
-    mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
-
-    mFlinger.updateLayerMetadataSnapshot();
-
-    EXPECT_EQ(layerA->getLayerSnapshot()->layerMetadata, layerAMetadata);
-    auto expectedChildMetadata =
-            LayerMetadataBuilder(layerAMetadata).setInt32(METADATA_TASK_ID, 3).build();
-    EXPECT_EQ(layerB->getLayerSnapshot()->layerMetadata, expectedChildMetadata);
-}
-
-// Test that snapshot relative layer metadata is set to the parent's layer metadata merged on top of
-// that parent's relative layer metadata.
-TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, updatesRelativeMetadata) {
-    auto layerAMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 1).build();
-    auto layerA = createLayer("relative-parent", layerAMetadata);
-    auto layerAHandle = layerA->getHandle();
-    auto layerBMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 2).build();
-    auto layerB = createLayer("relative-child", layerBMetadata);
-    layerB->setRelativeLayer(layerAHandle, 1);
-    mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
-    mFlinger.mutableDrawingState().layersSortedByZ.add(layerB);
-
-    mFlinger.updateLayerMetadataSnapshot();
-
-    EXPECT_EQ(layerA->getLayerSnapshot()->relativeLayerMetadata, LayerMetadata{});
-    EXPECT_EQ(layerB->getLayerSnapshot()->relativeLayerMetadata, layerAMetadata);
-}
-
-// Test that snapshot relative layer metadata is set correctly when a layer is interleaved within
-// two other layers.
-//
-// Layer
-//      A
-//     / \
-//    B   D
-//   /
-//  C
-//
-// Z-order Relatives
-//    B <- D <- C
-TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, updatesRelativeMetadataInterleaved) {
-    auto layerAMetadata = LayerMetadataBuilder().setInt32(METADATA_OWNER_UID, 1).build();
-    auto layerA = createLayer("layer-a", layerAMetadata);
-    auto layerBMetadata = LayerMetadataBuilder()
-                                  .setInt32(METADATA_TASK_ID, 2)
-                                  .setInt32(METADATA_OWNER_PID, 3)
-                                  .build();
-    auto layerB = createLayer("layer-b", layerBMetadata);
-    auto layerBHandle = layerB->getHandle();
-    LayerMetadata layerCMetadata;
-    auto layerC = createLayer("layer-c", layerCMetadata);
-    auto layerDMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 4).build();
-    auto layerD = createLayer("layer-d", layerDMetadata);
-    auto layerDHandle = layerD->getHandle();
-    layerB->addChild(layerC);
-    layerA->addChild(layerB);
-    layerA->addChild(layerD);
-    layerC->setRelativeLayer(layerDHandle, 1);
-    layerD->setRelativeLayer(layerBHandle, 1);
-    layerA->commitChildList();
-    mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
-
-    mFlinger.updateLayerMetadataSnapshot();
-
-    auto expectedLayerDRelativeMetadata =
-            LayerMetadataBuilder()
-                    // From layer A, parent of relative parent
-                    .setInt32(METADATA_OWNER_UID, 1)
-                    // From layer B, relative parent
-                    .setInt32(METADATA_TASK_ID, 2)
-                    .setInt32(METADATA_OWNER_PID, 3)
-                    // added by layer creation args
-                    .setInt32(gui::METADATA_CALLING_UID,
-                              layerDMetadata.getInt32(gui::METADATA_CALLING_UID, 0))
-                    .build();
-    EXPECT_EQ(layerD->getLayerSnapshot()->relativeLayerMetadata, expectedLayerDRelativeMetadata);
-    auto expectedLayerCRelativeMetadata =
-            LayerMetadataBuilder()
-                    // From layer A, parent of relative parent
-                    .setInt32(METADATA_OWNER_UID, 1)
-                    // From layer B, relative parent of relative parent
-                    .setInt32(METADATA_OWNER_PID, 3)
-                    // From layer D, relative parent
-                    .setInt32(METADATA_TASK_ID, 4)
-                    // added by layer creation args
-                    .setInt32(gui::METADATA_CALLING_UID,
-                              layerDMetadata.getInt32(gui::METADATA_CALLING_UID, 0))
-                    .build();
-    EXPECT_EQ(layerC->getLayerSnapshot()->relativeLayerMetadata, expectedLayerCRelativeMetadata);
-}
-
-TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest,
-       updatesRelativeMetadataMultipleRelativeChildren) {
-    auto layerAMetadata = LayerMetadataBuilder().setInt32(METADATA_OWNER_UID, 1).build();
-    auto layerA = createLayer("layer-a", layerAMetadata);
-    auto layerAHandle = layerA->getHandle();
-    LayerMetadata layerBMetadata;
-    auto layerB = createLayer("layer-b", layerBMetadata);
-    LayerMetadata layerCMetadata;
-    auto layerC = createLayer("layer-c", layerCMetadata);
-    layerB->setRelativeLayer(layerAHandle, 1);
-    layerC->setRelativeLayer(layerAHandle, 2);
-    layerA->commitChildList();
-    mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
-    mFlinger.mutableDrawingState().layersSortedByZ.add(layerB);
-    mFlinger.mutableDrawingState().layersSortedByZ.add(layerC);
-
-    mFlinger.updateLayerMetadataSnapshot();
-
-    EXPECT_EQ(layerA->getLayerSnapshot()->relativeLayerMetadata, LayerMetadata{});
-    EXPECT_EQ(layerB->getLayerSnapshot()->relativeLayerMetadata, layerAMetadata);
-    EXPECT_EQ(layerC->getLayerSnapshot()->relativeLayerMetadata, layerAMetadata);
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 5e81b35..a6a2758 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -584,8 +584,6 @@
         return mFlinger->mirrorLayer(args, mirrorFromHandle, outResult);
     }
 
-    void updateLayerMetadataSnapshot() { mFlinger->updateLayerMetadataSnapshot(); }
-
     void getDynamicDisplayInfoFromToken(const sp<IBinder>& displayToken,
                                         ui::DynamicDisplayInfo* dynamicDisplayInfo) {
         mFlinger->getDynamicDisplayInfoFromToken(displayToken, dynamicDisplayInfo);
diff --git a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
index 85b61f8..abfab9a 100644
--- a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
@@ -94,7 +94,7 @@
                                                          HAL_PIXEL_FORMAT_RGBA_8888,
                                                          0ULL /*usage*/);
         layer->setBuffer(externalTexture, bufferData, postTime, /*desiredPresentTime*/ 30, false,
-                         FrameTimelineInfo{});
+                         FrameTimelineInfo{}, gui::GameMode::Unsupported);
 
         commitTransaction(layer.get());
         nsecs_t latchTime = 25;
@@ -112,7 +112,8 @@
         EXPECT_CALL(*mFlinger.getFrameTracer(),
                     traceFence(layerId, bufferId, frameNumber, presentFence,
                                FrameTracer::FrameEvent::PRESENT_FENCE, /*startTime*/ 0));
-        layer->onCompositionPresented(nullptr, glDoneFence, presentFence, compositorTiming);
+        layer->onCompositionPresented(nullptr, glDoneFence, presentFence, compositorTiming,
+                                      gui::GameMode::Unsupported);
     }
 };
 
diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
index 0745f87..9a68d75 100644
--- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
@@ -72,7 +72,8 @@
         FrameTimelineInfo ftInfo;
         ftInfo.vsyncId = 1;
         ftInfo.inputEventId = 0;
-        layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10);
+        layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10,
+                                                             gui::GameMode::Unsupported);
         EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
         ASSERT_TRUE(layer->mDrawingState.bufferSurfaceFrameTX == nullptr);
         const auto surfaceFrame = layer->mDrawingState.bufferlessSurfaceFramesTX.at(/*token*/ 1);
@@ -99,7 +100,8 @@
         FrameTimelineInfo ftInfo;
         ftInfo.vsyncId = 1;
         ftInfo.inputEventId = 0;
-        layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo);
+        layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo,
+                         gui::GameMode::Unsupported);
         acquireFence->signalForTest(12);
 
         commitTransaction(layer.get());
@@ -134,7 +136,8 @@
         FrameTimelineInfo ftInfo;
         ftInfo.vsyncId = 1;
         ftInfo.inputEventId = 0;
-        layer->setBuffer(externalTexture1, bufferData, 10, 20, false, ftInfo);
+        layer->setBuffer(externalTexture1, bufferData, 10, 20, false, ftInfo,
+                         gui::GameMode::Unsupported);
         EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
         ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
         const auto droppedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
@@ -151,7 +154,8 @@
                                                          2ULL /* bufferId */,
                                                          HAL_PIXEL_FORMAT_RGBA_8888,
                                                          0ULL /*usage*/);
-        layer->setBuffer(externalTexture2, bufferData, 10, 20, false, ftInfo);
+        layer->setBuffer(externalTexture2, bufferData, 10, 20, false, ftInfo,
+                         gui::GameMode::Unsupported);
         nsecs_t end = systemTime();
         acquireFence2->signalForTest(12);
 
@@ -180,7 +184,8 @@
         ftInfo.vsyncId = 1;
         ftInfo.inputEventId = 0;
 
-        layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10);
+        layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10,
+                                                             gui::GameMode::Unsupported);
 
         EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
         ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
@@ -197,7 +202,8 @@
                                                          1ULL /* bufferId */,
                                                          HAL_PIXEL_FORMAT_RGBA_8888,
                                                          0ULL /*usage*/);
-        layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo);
+        layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo,
+                         gui::GameMode::Unsupported);
         acquireFence->signalForTest(12);
 
         EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
@@ -232,11 +238,13 @@
         FrameTimelineInfo ftInfo;
         ftInfo.vsyncId = 1;
         ftInfo.inputEventId = 0;
-        layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo);
+        layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo,
+                         gui::GameMode::Unsupported);
         EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
         ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
 
-        layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10);
+        layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10,
+                                                             gui::GameMode::Unsupported);
         EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
         ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
     }
@@ -246,7 +254,8 @@
         FrameTimelineInfo ftInfo;
         ftInfo.vsyncId = 1;
         ftInfo.inputEventId = 0;
-        layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10);
+        layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10,
+                                                             gui::GameMode::Unsupported);
         EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
         ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
         const auto bufferlessSurfaceFrame1 =
@@ -255,7 +264,8 @@
         FrameTimelineInfo ftInfo2;
         ftInfo2.vsyncId = 4;
         ftInfo2.inputEventId = 0;
-        layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo2, 10);
+        layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo2, 10,
+                                                             gui::GameMode::Unsupported);
         EXPECT_EQ(2u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
         ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
         const auto bufferlessSurfaceFrame2 = layer->mDrawingState.bufferlessSurfaceFramesTX[4];
@@ -275,7 +285,8 @@
         FrameTimelineInfo ftInfo3;
         ftInfo3.vsyncId = 3;
         ftInfo3.inputEventId = 0;
-        layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo3);
+        layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo3,
+                         gui::GameMode::Unsupported);
         EXPECT_EQ(2u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
         ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
         const auto bufferSurfaceFrameTX = layer->mDrawingState.bufferSurfaceFrameTX;
@@ -320,7 +331,8 @@
         FrameTimelineInfo ftInfo;
         ftInfo.vsyncId = 1;
         ftInfo.inputEventId = 0;
-        layer->setBuffer(externalTexture1, bufferData, 10, 20, false, ftInfo);
+        layer->setBuffer(externalTexture1, bufferData, 10, 20, false, ftInfo,
+                         gui::GameMode::Unsupported);
         EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
         ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
         const auto droppedSurfaceFrame1 = layer->mDrawingState.bufferSurfaceFrameTX;
@@ -340,7 +352,8 @@
         FrameTimelineInfo ftInfoInv;
         ftInfoInv.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
         ftInfoInv.inputEventId = 0;
-        layer->setBuffer(externalTexture2, bufferData, 10, 20, false, ftInfoInv);
+        layer->setBuffer(externalTexture2, bufferData, 10, 20, false, ftInfoInv,
+                         gui::GameMode::Unsupported);
         auto dropEndTime1 = systemTime();
         EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
         ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
@@ -361,7 +374,8 @@
         FrameTimelineInfo ftInfo2;
         ftInfo2.vsyncId = 2;
         ftInfo2.inputEventId = 0;
-        layer->setBuffer(externalTexture3, bufferData, 10, 20, false, ftInfo2);
+        layer->setBuffer(externalTexture3, bufferData, 10, 20, false, ftInfo2,
+                         gui::GameMode::Unsupported);
         auto dropEndTime2 = systemTime();
         acquireFence3->signalForTest(12);
 
@@ -409,11 +423,13 @@
             FrameTimelineInfo ftInfo;
             ftInfo.vsyncId = 1;
             ftInfo.inputEventId = 0;
-            layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo);
+            layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo,
+                             gui::GameMode::Unsupported);
             FrameTimelineInfo ftInfo2;
             ftInfo2.vsyncId = 2;
             ftInfo2.inputEventId = 0;
-            layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo2, 10);
+            layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo2, 10,
+                                                                 gui::GameMode::Unsupported);
             ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
             EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
 
diff --git a/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
index 1cf14ae..9f6065b 100644
--- a/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
@@ -127,7 +127,7 @@
     sp<NativeHandle> stream =
             NativeHandle::create(reinterpret_cast<native_handle_t*>(DEFAULT_SIDEBAND_STREAM),
                                  false);
-    layer->setSidebandStream(stream, FrameTimelineInfo{}, 20);
+    layer->setSidebandStream(stream, FrameTimelineInfo{}, 20, gui::GameMode::Unsupported);
     mFlinger.mutableCurrentState().layersSortedByZ.add(layer);
     mTunnelModeEnabledReporter->updateTunnelModeStatus();
     mTunnelModeEnabledReporter->addListener(mTunnelModeEnabledListener);
@@ -151,7 +151,8 @@
     sp<NativeHandle> stream =
             NativeHandle::create(reinterpret_cast<native_handle_t*>(DEFAULT_SIDEBAND_STREAM),
                                  false);
-    layerWithSidebandStream->setSidebandStream(stream, FrameTimelineInfo{}, 20);
+    layerWithSidebandStream->setSidebandStream(stream, FrameTimelineInfo{}, 20,
+                                               gui::GameMode::Unsupported);
 
     mFlinger.mutableCurrentState().layersSortedByZ.add(simpleLayer);
     mFlinger.mutableCurrentState().layersSortedByZ.add(layerWithSidebandStream);