SF: Populate allowGroupSwitching from DM

Currently we use allowGroupSwitching only for testing. This CL
populates its value from DisplayManager so we can use user
setting to change its value.

Bug: 161776333
Test: atest libsurfaceflinger_unittest
Change-Id: I851eaee7f86083d97204cf3553e728350c942dfe
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 964195d..6f92233 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -888,7 +888,7 @@
     }
 
     virtual status_t setDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
-                                                  int32_t defaultConfig,
+                                                  int32_t defaultConfig, bool allowGroupSwitching,
                                                   float primaryRefreshRateMin,
                                                   float primaryRefreshRateMax,
                                                   float appRequestRefreshRateMin,
@@ -909,6 +909,11 @@
             ALOGE("setDesiredDisplayConfigSpecs failed to write defaultConfig: %d", result);
             return result;
         }
+        result = data.writeBool(allowGroupSwitching);
+        if (result != NO_ERROR) {
+            ALOGE("setDesiredDisplayConfigSpecs failed to write allowGroupSwitching: %d", result);
+            return result;
+        }
         result = data.writeFloat(primaryRefreshRateMin);
         if (result != NO_ERROR) {
             ALOGE("setDesiredDisplayConfigSpecs failed to write primaryRefreshRateMin: %d", result);
@@ -943,12 +948,14 @@
 
     virtual status_t getDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
                                                   int32_t* outDefaultConfig,
+                                                  bool* outAllowGroupSwitching,
                                                   float* outPrimaryRefreshRateMin,
                                                   float* outPrimaryRefreshRateMax,
                                                   float* outAppRequestRefreshRateMin,
                                                   float* outAppRequestRefreshRateMax) {
-        if (!outDefaultConfig || !outPrimaryRefreshRateMin || !outPrimaryRefreshRateMax ||
-            !outAppRequestRefreshRateMin || !outAppRequestRefreshRateMax) {
+        if (!outDefaultConfig || !outAllowGroupSwitching || !outPrimaryRefreshRateMin ||
+            !outPrimaryRefreshRateMax || !outAppRequestRefreshRateMin ||
+            !outAppRequestRefreshRateMax) {
             return BAD_VALUE;
         }
         Parcel data, reply;
@@ -973,6 +980,11 @@
             ALOGE("getDesiredDisplayConfigSpecs failed to read defaultConfig: %d", result);
             return result;
         }
+        result = reply.readBool(outAllowGroupSwitching);
+        if (result != NO_ERROR) {
+            ALOGE("getDesiredDisplayConfigSpecs failed to read allowGroupSwitching: %d", result);
+            return result;
+        }
         result = reply.readFloat(outPrimaryRefreshRateMin);
         if (result != NO_ERROR) {
             ALOGE("getDesiredDisplayConfigSpecs failed to read primaryRefreshRateMin: %d", result);
@@ -1829,6 +1841,13 @@
                 ALOGE("setDesiredDisplayConfigSpecs: failed to read defaultConfig: %d", result);
                 return result;
             }
+            bool allowGroupSwitching;
+            result = data.readBool(&allowGroupSwitching);
+            if (result != NO_ERROR) {
+                ALOGE("setDesiredDisplayConfigSpecs: failed to read allowGroupSwitching: %d",
+                      result);
+                return result;
+            }
             float primaryRefreshRateMin;
             result = data.readFloat(&primaryRefreshRateMin);
             if (result != NO_ERROR) {
@@ -1857,10 +1876,10 @@
                       result);
                 return result;
             }
-            result =
-                    setDesiredDisplayConfigSpecs(displayToken, defaultConfig, primaryRefreshRateMin,
-                                                 primaryRefreshRateMax, appRequestRefreshRateMin,
-                                                 appRequestRefreshRateMax);
+            result = setDesiredDisplayConfigSpecs(displayToken, defaultConfig, allowGroupSwitching,
+                                                  primaryRefreshRateMin, primaryRefreshRateMax,
+                                                  appRequestRefreshRateMin,
+                                                  appRequestRefreshRateMax);
             if (result != NO_ERROR) {
                 ALOGE("setDesiredDisplayConfigSpecs: failed to call setDesiredDisplayConfigSpecs: "
                       "%d",
@@ -1874,13 +1893,14 @@
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> displayToken = data.readStrongBinder();
             int32_t defaultConfig;
+            bool allowGroupSwitching;
             float primaryRefreshRateMin;
             float primaryRefreshRateMax;
             float appRequestRefreshRateMin;
             float appRequestRefreshRateMax;
 
             status_t result =
-                    getDesiredDisplayConfigSpecs(displayToken, &defaultConfig,
+                    getDesiredDisplayConfigSpecs(displayToken, &defaultConfig, &allowGroupSwitching,
                                                  &primaryRefreshRateMin, &primaryRefreshRateMax,
                                                  &appRequestRefreshRateMin,
                                                  &appRequestRefreshRateMax);
@@ -1896,6 +1916,12 @@
                 ALOGE("getDesiredDisplayConfigSpecs: failed to write defaultConfig: %d", result);
                 return result;
             }
+            result = reply->writeBool(allowGroupSwitching);
+            if (result != NO_ERROR) {
+                ALOGE("getDesiredDisplayConfigSpecs: failed to write allowGroupSwitching: %d",
+                      result);
+                return result;
+            }
             result = reply->writeFloat(primaryRefreshRateMin);
             if (result != NO_ERROR) {
                 ALOGE("getDesiredDisplayConfigSpecs: failed to write primaryRefreshRateMin: %d",
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 105969b..d3ea5ed 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1774,27 +1774,24 @@
     return ComposerService::getComposerService()->getActiveConfig(display);
 }
 
-status_t SurfaceComposerClient::setDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
-                                                             int32_t defaultConfig,
-                                                             float primaryRefreshRateMin,
-                                                             float primaryRefreshRateMax,
-                                                             float appRequestRefreshRateMin,
-                                                             float appRequestRefreshRateMax) {
+status_t SurfaceComposerClient::setDesiredDisplayConfigSpecs(
+        const sp<IBinder>& displayToken, int32_t defaultConfig, bool allowGroupSwitching,
+        float primaryRefreshRateMin, float primaryRefreshRateMax, float appRequestRefreshRateMin,
+        float appRequestRefreshRateMax) {
     return ComposerService::getComposerService()
-            ->setDesiredDisplayConfigSpecs(displayToken, defaultConfig, primaryRefreshRateMin,
-                                           primaryRefreshRateMax, appRequestRefreshRateMin,
-                                           appRequestRefreshRateMax);
+            ->setDesiredDisplayConfigSpecs(displayToken, defaultConfig, allowGroupSwitching,
+                                           primaryRefreshRateMin, primaryRefreshRateMax,
+                                           appRequestRefreshRateMin, appRequestRefreshRateMax);
 }
 
-status_t SurfaceComposerClient::getDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
-                                                             int32_t* outDefaultConfig,
-                                                             float* outPrimaryRefreshRateMin,
-                                                             float* outPrimaryRefreshRateMax,
-                                                             float* outAppRequestRefreshRateMin,
-                                                             float* outAppRequestRefreshRateMax) {
+status_t SurfaceComposerClient::getDesiredDisplayConfigSpecs(
+        const sp<IBinder>& displayToken, int32_t* outDefaultConfig, bool* outAllowGroupSwitching,
+        float* outPrimaryRefreshRateMin, float* outPrimaryRefreshRateMax,
+        float* outAppRequestRefreshRateMin, float* outAppRequestRefreshRateMax) {
     return ComposerService::getComposerService()
-            ->getDesiredDisplayConfigSpecs(displayToken, outDefaultConfig, outPrimaryRefreshRateMin,
-                                           outPrimaryRefreshRateMax, outAppRequestRefreshRateMin,
+            ->getDesiredDisplayConfigSpecs(displayToken, outDefaultConfig, outAllowGroupSwitching,
+                                           outPrimaryRefreshRateMin, outPrimaryRefreshRateMax,
+                                           outAppRequestRefreshRateMin,
                                            outAppRequestRefreshRateMax);
 }
 
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index a416147..5cd9356 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -395,7 +395,7 @@
      * returned from getDisplayConfigs().
      */
     virtual status_t setDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
-                                                  int32_t defaultConfig,
+                                                  int32_t defaultConfig, bool allowGroupSwitching,
                                                   float primaryRefreshRateMin,
                                                   float primaryRefreshRateMax,
                                                   float appRequestRefreshRateMin,
@@ -403,6 +403,7 @@
 
     virtual status_t getDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
                                                   int32_t* outDefaultConfig,
+                                                  bool* outAllowGroupSwitching,
                                                   float* outPrimaryRefreshRateMin,
                                                   float* outPrimaryRefreshRateMax,
                                                   float* outAppRequestRefreshRateMin,
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index ce1a0a5..5d05e27 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -120,13 +120,15 @@
 
     // Sets the refresh rate boundaries for the display.
     static status_t setDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
-                                                 int32_t defaultConfig, float primaryRefreshRateMin,
+                                                 int32_t defaultConfig, bool allowGroupSwitching,
+                                                 float primaryRefreshRateMin,
                                                  float primaryRefreshRateMax,
                                                  float appRequestRefreshRateMin,
                                                  float appRequestRefreshRateMax);
     // Gets the refresh rate boundaries for the display.
     static status_t getDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
                                                  int32_t* outDefaultConfig,
+                                                 bool* outAllowGroupSwitching,
                                                  float* outPrimaryRefreshRateMin,
                                                  float* outPrimaryRefreshRateMax,
                                                  float* outAppRequestRefreshRateMin,
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 5a376da..0cd3962 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -844,7 +844,7 @@
         return NO_ERROR;
     }
     status_t setDesiredDisplayConfigSpecs(const sp<IBinder>& /*displayToken*/,
-                                          int32_t /*defaultConfig*/,
+                                          int32_t /*defaultConfig*/, bool /*allowGroupSwitching*/,
                                           float /*primaryRefreshRateMin*/,
                                           float /*primaryRefreshRateMax*/,
                                           float /*appRequestRefreshRateMin*/,
@@ -853,6 +853,7 @@
     }
     status_t getDesiredDisplayConfigSpecs(const sp<IBinder>& /*displayToken*/,
                                           int32_t* /*outDefaultConfig*/,
+                                          bool* /*outAllowGroupSwitching*/,
                                           float* /*outPrimaryRefreshRateMin*/,
                                           float* /*outPrimaryRefreshRateMax*/,
                                           float* /*outAppRequestRefreshRateMin*/,
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 8661b6e..7ab49a9 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -48,6 +48,13 @@
     }
 }
 
+std::string RefreshRateConfigs::Policy::toString() {
+    return base::StringPrintf("default config ID: %d, allowGroupSwitching = %d"
+                              ", primary range: [%.2f %.2f], app request range: [%.2f %.2f]",
+                              defaultConfig.value(), allowGroupSwitching, primaryRange.min,
+                              primaryRange.max, appRequestRange.min, appRequestRange.max);
+}
+
 const RefreshRate& RefreshRateConfigs::getRefreshRateForContent(
         const std::vector<LayerRequirement>& layers) const {
     std::lock_guard lock(mLock);
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index eed8486..280ed62 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -108,6 +108,10 @@
             std::unordered_map<HwcConfigIndexType, std::unique_ptr<const RefreshRate>>;
 
     struct Policy {
+    private:
+        static constexpr int kAllowGroupSwitchingDefault = false;
+
+    public:
         struct Range {
             float min = 0;
             float max = std::numeric_limits<float>::max();
@@ -122,6 +126,8 @@
         // The default config, used to ensure we only initiate display config switches within the
         // same config group as defaultConfigId's group.
         HwcConfigIndexType defaultConfig;
+        // Whether or not we switch config groups to get the best frame rate.
+        bool allowGroupSwitching = kAllowGroupSwitchingDefault;
         // The primary refresh rate range represents display manager's general guidance on the
         // display configs we'll consider when switching refresh rates. Unless we get an explicit
         // signal from an app, we should stay within this range.
@@ -133,15 +139,23 @@
         // app request range. The app request range will be greater than or equal to the primary
         // refresh rate range, never smaller.
         Range appRequestRange;
-        // Whether or not we switch config groups to get the best frame rate. Only used by tests.
-        bool allowGroupSwitching = false;
 
         Policy() = default;
+
         Policy(HwcConfigIndexType defaultConfig, const Range& range)
-              : Policy(defaultConfig, range, range) {}
+              : Policy(defaultConfig, kAllowGroupSwitchingDefault, range, range) {}
+
+        Policy(HwcConfigIndexType defaultConfig, bool allowGroupSwitching, const Range& range)
+              : Policy(defaultConfig, allowGroupSwitching, range, range) {}
+
         Policy(HwcConfigIndexType defaultConfig, const Range& primaryRange,
                const Range& appRequestRange)
+              : Policy(defaultConfig, kAllowGroupSwitchingDefault, primaryRange, appRequestRange) {}
+
+        Policy(HwcConfigIndexType defaultConfig, bool allowGroupSwitching,
+               const Range& primaryRange, const Range& appRequestRange)
               : defaultConfig(defaultConfig),
+                allowGroupSwitching(allowGroupSwitching),
                 primaryRange(primaryRange),
                 appRequestRange(appRequestRange) {}
 
@@ -152,6 +166,7 @@
         }
 
         bool operator!=(const Policy& other) const { return !(*this == other); }
+        std::string toString();
     };
 
     // Return code set*Policy() to indicate the current policy is unchanged.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 964bd01..a886f5f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1041,7 +1041,12 @@
         } else {
             const HwcConfigIndexType config(mode);
             const float fps = mRefreshRateConfigs->getRefreshRateFromConfigId(config).getFps();
-            const scheduler::RefreshRateConfigs::Policy policy{config, {fps, fps}};
+            // Keep the old switching type.
+            const auto allowGroupSwitching =
+                    mRefreshRateConfigs->getCurrentPolicy().allowGroupSwitching;
+            const scheduler::RefreshRateConfigs::Policy policy{config,
+                                                               allowGroupSwitching,
+                                                               {fps, fps}};
             constexpr bool kOverridePolicy = false;
 
             return setDesiredDisplayConfigSpecsInternal(display, policy, kOverridePolicy);
@@ -4356,21 +4361,14 @@
                   dispSyncPresentTimeOffset, getVsyncPeriodFromHWC());
 
     scheduler::RefreshRateConfigs::Policy policy = mRefreshRateConfigs->getDisplayManagerPolicy();
-    StringAppendF(&result,
-                  "DesiredDisplayConfigSpecs (DisplayManager): default config ID: %d"
-                  ", primary range: [%.2f %.2f], app request range: [%.2f %.2f]\n\n",
-                  policy.defaultConfig.value(), policy.primaryRange.min, policy.primaryRange.max,
-                  policy.appRequestRange.min, policy.appRequestRange.max);
+    StringAppendF(&result, "DesiredDisplayConfigSpecs (DisplayManager): %s\n\n",
+                  policy.toString().c_str());
     StringAppendF(&result, "(config override by backdoor: %s)\n\n",
                   mDebugDisplayConfigSetByBackdoor ? "yes" : "no");
     scheduler::RefreshRateConfigs::Policy currentPolicy = mRefreshRateConfigs->getCurrentPolicy();
     if (currentPolicy != policy) {
-        StringAppendF(&result,
-                      "DesiredDisplayConfigSpecs (Override): default config ID: %d"
-                      ", primary range: [%.2f %.2f], app request range: [%.2f %.2f]\n\n",
-                      currentPolicy.defaultConfig.value(), currentPolicy.primaryRange.min,
-                      currentPolicy.primaryRange.max, currentPolicy.appRequestRange.min,
-                      currentPolicy.appRequestRange.max);
+        StringAppendF(&result, "DesiredDisplayConfigSpecs (Override): %s\n\n",
+                      currentPolicy.toString().c_str());
     }
 
     mScheduler->dump(mAppConnectionHandle, result);
@@ -5964,12 +5962,10 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::setDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
-                                                      int32_t defaultConfig,
-                                                      float primaryRefreshRateMin,
-                                                      float primaryRefreshRateMax,
-                                                      float appRequestRefreshRateMin,
-                                                      float appRequestRefreshRateMax) {
+status_t SurfaceFlinger::setDesiredDisplayConfigSpecs(
+        const sp<IBinder>& displayToken, int32_t defaultConfig, bool allowGroupSwitching,
+        float primaryRefreshRateMin, float primaryRefreshRateMax, float appRequestRefreshRateMin,
+        float appRequestRefreshRateMax) {
     ATRACE_CALL();
 
     if (!displayToken) {
@@ -5988,6 +5984,7 @@
         } else {
             using Policy = scheduler::RefreshRateConfigs::Policy;
             const Policy policy{HwcConfigIndexType(defaultConfig),
+                                allowGroupSwitching,
                                 {primaryRefreshRateMin, primaryRefreshRateMax},
                                 {appRequestRefreshRateMin, appRequestRefreshRateMax}};
             constexpr bool kOverridePolicy = false;
@@ -5999,12 +5996,10 @@
     return future.get();
 }
 
-status_t SurfaceFlinger::getDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
-                                                      int32_t* outDefaultConfig,
-                                                      float* outPrimaryRefreshRateMin,
-                                                      float* outPrimaryRefreshRateMax,
-                                                      float* outAppRequestRefreshRateMin,
-                                                      float* outAppRequestRefreshRateMax) {
+status_t SurfaceFlinger::getDesiredDisplayConfigSpecs(
+        const sp<IBinder>& displayToken, int32_t* outDefaultConfig, bool* outAllowGroupSwitching,
+        float* outPrimaryRefreshRateMin, float* outPrimaryRefreshRateMax,
+        float* outAppRequestRefreshRateMin, float* outAppRequestRefreshRateMax) {
     ATRACE_CALL();
 
     if (!displayToken || !outDefaultConfig || !outPrimaryRefreshRateMin ||
@@ -6022,6 +6017,7 @@
         scheduler::RefreshRateConfigs::Policy policy =
                 mRefreshRateConfigs->getDisplayManagerPolicy();
         *outDefaultConfig = policy.defaultConfig.value();
+        *outAllowGroupSwitching = policy.allowGroupSwitching;
         *outPrimaryRefreshRateMin = policy.primaryRange.min;
         *outPrimaryRefreshRateMax = policy.primaryRange.max;
         *outAppRequestRefreshRateMin = policy.appRequestRange.min;
@@ -6032,6 +6028,7 @@
     } else {
         const auto displayId = display->getPhysicalId();
         *outDefaultConfig = getHwComposer().getActiveConfigIndex(displayId);
+        *outAllowGroupSwitching = false;
         auto vsyncPeriod = getHwComposer().getActiveConfig(displayId)->getVsyncPeriod();
         *outPrimaryRefreshRateMin = 1e9f / vsyncPeriod;
         *outPrimaryRefreshRateMax = 1e9f / vsyncPeriod;
@@ -6162,8 +6159,8 @@
             // This is a little racy, but not in a way that hurts anything. As we grab the
             // defaultConfig from the display manager policy, we could be setting a new display
             // manager policy, leaving us using a stale defaultConfig. The defaultConfig doesn't
-            // matter for the override policy though, since we set allowGroupSwitching to true, so
-            // it's not a problem.
+            // matter for the override policy though, since we set allowGroupSwitching to
+            // true, so it's not a problem.
             scheduler::RefreshRateConfigs::Policy overridePolicy;
             overridePolicy.defaultConfig =
                     mRefreshRateConfigs->getDisplayManagerPolicy().defaultConfig;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 5bb5a0d..4f1f1c1 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -583,11 +583,12 @@
                                        const sp<IRegionSamplingListener>& listener) override;
     status_t removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) override;
     status_t setDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken, int32_t displayModeId,
-                                          float primaryRefreshRateMin, float primaryRefreshRateMax,
+                                          bool allowGroupSwitching, float primaryRefreshRateMin,
+                                          float primaryRefreshRateMax,
                                           float appRequestRefreshRateMin,
                                           float appRequestRefreshRateMax) override;
     status_t getDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
-                                          int32_t* outDefaultConfig,
+                                          int32_t* outDefaultConfig, bool* outAllowGroupSwitching,
                                           float* outPrimaryRefreshRateMin,
                                           float* outPrimaryRefreshRateMax,
                                           float* outAppRequestRefreshRateMin,
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index 7f541e2..9302463 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -218,18 +218,21 @@
 TEST_F(CredentialsTest, SetDesiredDisplayConfigsTest) {
     const auto display = SurfaceComposerClient::getInternalDisplayToken();
     int32_t defaultConfig;
+    bool allowGroupSwitching;
     float primaryFpsMin;
     float primaryFpsMax;
     float appRequestFpsMin;
     float appRequestFpsMax;
     status_t res =
             SurfaceComposerClient::getDesiredDisplayConfigSpecs(display, &defaultConfig,
+                                                                &allowGroupSwitching,
                                                                 &primaryFpsMin, &primaryFpsMax,
                                                                 &appRequestFpsMin,
                                                                 &appRequestFpsMax);
     ASSERT_EQ(res, NO_ERROR);
     std::function<status_t()> condition = [=]() {
         return SurfaceComposerClient::setDesiredDisplayConfigSpecs(display, defaultConfig,
+                                                                   allowGroupSwitching,
                                                                    primaryFpsMin, primaryFpsMax,
                                                                    appRequestFpsMin,
                                                                    appRequestFpsMax);
diff --git a/services/surfaceflinger/tests/DisplayConfigs_test.cpp b/services/surfaceflinger/tests/DisplayConfigs_test.cpp
index debfe83..3a8b40f 100644
--- a/services/surfaceflinger/tests/DisplayConfigs_test.cpp
+++ b/services/surfaceflinger/tests/DisplayConfigs_test.cpp
@@ -14,16 +14,18 @@
  * limitations under the License.
  */
 
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
+#include <gtest/gtest.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <private/gui/ComposerService.h>
+#include <ui/DisplayConfig.h>
+#include <utils/Errors.h>
+#include <utils/Vector.h>
 
-#include <thread>
-#include "LayerTransactionTest.h"
+#include "utils/TransactionUtils.h"
+
 namespace android {
 
-using android::hardware::graphics::common::V1_1::BufferUsage;
-
 ::testing::Environment* const binderEnv =
         ::testing::AddGlobalTestEnvironment(new BinderEnvironment());
 
@@ -31,32 +33,54 @@
  * Test class for setting display configs and passing around refresh rate ranges.
  */
 class RefreshRateRangeTest : public ::testing::Test {
+private:
+    int32_t initialDefaultConfig;
+    bool initialAllowGroupSwitching;
+    float initialPrimaryMin;
+    float initialPrimaryMax;
+    float initialAppRequestMin;
+    float initialAppRequestMax;
+
 protected:
-    void SetUp() override { mDisplayToken = SurfaceComposerClient::getInternalDisplayToken(); }
+    void SetUp() override {
+        mDisplayToken = SurfaceComposerClient::getInternalDisplayToken();
+        status_t res =
+                SurfaceComposerClient::getDesiredDisplayConfigSpecs(mDisplayToken,
+                                                                    &initialDefaultConfig,
+                                                                    &initialAllowGroupSwitching,
+                                                                    &initialPrimaryMin,
+                                                                    &initialPrimaryMax,
+                                                                    &initialAppRequestMin,
+                                                                    &initialAppRequestMax);
+        ASSERT_EQ(res, NO_ERROR);
+    }
+
+    void TearDown() override {
+        status_t res =
+                SurfaceComposerClient::setDesiredDisplayConfigSpecs(mDisplayToken,
+                                                                    initialDefaultConfig,
+                                                                    initialAllowGroupSwitching,
+                                                                    initialPrimaryMin,
+                                                                    initialPrimaryMax,
+                                                                    initialAppRequestMin,
+                                                                    initialAppRequestMax);
+        ASSERT_EQ(res, NO_ERROR);
+    }
+
+    void testSetAllowGroupSwitching(bool allowGroupSwitching);
 
     sp<IBinder> mDisplayToken;
 };
 
 TEST_F(RefreshRateRangeTest, setAllConfigs) {
-    int32_t initialDefaultConfig;
-    float initialPrimaryMin;
-    float initialPrimaryMax;
-    float initialAppRequestMin;
-    float initialAppRequestMax;
-    status_t res = SurfaceComposerClient::getDesiredDisplayConfigSpecs(mDisplayToken,
-                                                                       &initialDefaultConfig,
-                                                                       &initialPrimaryMin,
-                                                                       &initialPrimaryMax,
-                                                                       &initialAppRequestMin,
-                                                                       &initialAppRequestMax);
-    ASSERT_EQ(res, NO_ERROR);
-
     Vector<DisplayConfig> configs;
-    res = SurfaceComposerClient::getDisplayConfigs(mDisplayToken, &configs);
+    status_t res = SurfaceComposerClient::getDisplayConfigs(mDisplayToken, &configs);
     ASSERT_EQ(res, NO_ERROR);
+    ASSERT_GT(configs.size(), 0);
 
     for (size_t i = 0; i < configs.size(); i++) {
-        res = SurfaceComposerClient::setDesiredDisplayConfigSpecs(mDisplayToken, i,
+        res = SurfaceComposerClient::setDesiredDisplayConfigSpecs(mDisplayToken,
+                                                                  static_cast<int32_t>(i), false,
                                                                   configs[i].refreshRate,
                                                                   configs[i].refreshRate,
                                                                   configs[i].refreshRate,
@@ -64,31 +88,58 @@
         ASSERT_EQ(res, NO_ERROR);
 
         int defaultConfig;
+        bool allowGroupSwitching;
         float primaryRefreshRateMin;
         float primaryRefreshRateMax;
         float appRequestRefreshRateMin;
         float appRequestRefreshRateMax;
         res = SurfaceComposerClient::getDesiredDisplayConfigSpecs(mDisplayToken, &defaultConfig,
+                                                                  &allowGroupSwitching,
                                                                   &primaryRefreshRateMin,
                                                                   &primaryRefreshRateMax,
                                                                   &appRequestRefreshRateMin,
                                                                   &appRequestRefreshRateMax);
         ASSERT_EQ(res, NO_ERROR);
         ASSERT_EQ(defaultConfig, i);
+        ASSERT_EQ(allowGroupSwitching, false);
         ASSERT_EQ(primaryRefreshRateMin, configs[i].refreshRate);
         ASSERT_EQ(primaryRefreshRateMax, configs[i].refreshRate);
         ASSERT_EQ(appRequestRefreshRateMin, configs[i].refreshRate);
         ASSERT_EQ(appRequestRefreshRateMax, configs[i].refreshRate);
     }
+}
 
-    res = SurfaceComposerClient::setDesiredDisplayConfigSpecs(mDisplayToken, initialDefaultConfig,
-                                                              initialPrimaryMin, initialPrimaryMax,
-                                                              initialAppRequestMin,
-                                                              initialAppRequestMax);
+void RefreshRateRangeTest::testSetAllowGroupSwitching(bool allowGroupSwitching) {
+    status_t res = SurfaceComposerClient::setDesiredDisplayConfigSpecs(mDisplayToken, 0,
+                                                                       allowGroupSwitching, 0.f,
+                                                                       90.f, 0.f, 90.f);
     ASSERT_EQ(res, NO_ERROR);
+    int defaultConfig;
+    bool newAllowGroupSwitching;
+    float primaryRefreshRateMin;
+    float primaryRefreshRateMax;
+    float appRequestRefreshRateMin;
+    float appRequestRefreshRateMax;
+
+    res = SurfaceComposerClient::getDesiredDisplayConfigSpecs(mDisplayToken, &defaultConfig,
+                                                              &newAllowGroupSwitching,
+                                                              &primaryRefreshRateMin,
+                                                              &primaryRefreshRateMax,
+                                                              &appRequestRefreshRateMin,
+                                                              &appRequestRefreshRateMax);
+    ASSERT_EQ(res, NO_ERROR);
+    ASSERT_EQ(defaultConfig, 0);
+    ASSERT_EQ(newAllowGroupSwitching, allowGroupSwitching);
+    ASSERT_EQ(primaryRefreshRateMin, 0.f);
+    ASSERT_EQ(primaryRefreshRateMax, 90.f);
+    ASSERT_EQ(appRequestRefreshRateMin, 0.f);
+    ASSERT_EQ(appRequestRefreshRateMax, 90.f);
+}
+
+TEST_F(RefreshRateRangeTest, setAllowGroupSwitching) {
+    testSetAllowGroupSwitching(true);
+    testSetAllowGroupSwitching(false);
+    testSetAllowGroupSwitching(true);
 }
 
 } // namespace android
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h
index d4e952a..5fe2e40 100644
--- a/services/surfaceflinger/tests/LayerTransactionTest.h
+++ b/services/surfaceflinger/tests/LayerTransactionTest.h
@@ -16,6 +16,10 @@
 
 #pragma once
 
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
 #include <gtest/gtest.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/SurfaceComposerClient.h>
@@ -299,3 +303,6 @@
 };
 
 } // namespace android
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop // ignored "-Wconversion"
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
index 1606f22..34993ab 100644
--- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
+++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
@@ -447,7 +447,7 @@
             const auto& config = configs[i];
             if (config.resolution.getWidth() == 800) {
                 EXPECT_EQ(NO_ERROR,
-                          SurfaceComposerClient::setDesiredDisplayConfigSpecs(display, i,
+                          SurfaceComposerClient::setDesiredDisplayConfigSpecs(display, i, false,
                                                                               config.refreshRate,
                                                                               config.refreshRate,
                                                                               config.refreshRate,
@@ -553,7 +553,7 @@
             const auto& config = configs[i];
             if (config.refreshRate == 1e9f / 11'111'111) {
                 EXPECT_EQ(NO_ERROR,
-                          SurfaceComposerClient::setDesiredDisplayConfigSpecs(display, i,
+                          SurfaceComposerClient::setDesiredDisplayConfigSpecs(display, i, false,
                                                                               config.refreshRate,
                                                                               config.refreshRate,
                                                                               config.refreshRate,
@@ -670,7 +670,8 @@
             if (config.resolution.getWidth() == 800 && config.refreshRate == 1e9f / 11'111'111) {
                 EXPECT_EQ(NO_ERROR,
                           SurfaceComposerClient::
-                                  setDesiredDisplayConfigSpecs(display, i, configs[i].refreshRate,
+                                  setDesiredDisplayConfigSpecs(display, i, false,
+                                                               configs[i].refreshRate,
                                                                configs[i].refreshRate,
                                                                configs[i].refreshRate,
                                                                configs[i].refreshRate));
@@ -716,7 +717,7 @@
             const auto& config = configs[i];
             if (config.refreshRate == 1e9f / 8'333'333) {
                 EXPECT_EQ(NO_ERROR,
-                          SurfaceComposerClient::setDesiredDisplayConfigSpecs(display, i,
+                          SurfaceComposerClient::setDesiredDisplayConfigSpecs(display, i, false,
                                                                               config.refreshRate,
                                                                               config.refreshRate,
                                                                               config.refreshRate,
@@ -763,7 +764,7 @@
             const auto& config = configs[i];
             if (config.resolution.getWidth() == 1600 && config.refreshRate == 1e9f / 11'111'111) {
                 EXPECT_EQ(NO_ERROR,
-                          SurfaceComposerClient::setDesiredDisplayConfigSpecs(display, i,
+                          SurfaceComposerClient::setDesiredDisplayConfigSpecs(display, i, false,
                                                                               config.refreshRate,
                                                                               config.refreshRate,
                                                                               config.refreshRate,
diff --git a/services/surfaceflinger/tests/utils/TransactionUtils.h b/services/surfaceflinger/tests/utils/TransactionUtils.h
index 8e1f943..5c5b18e 100644
--- a/services/surfaceflinger/tests/utils/TransactionUtils.h
+++ b/services/surfaceflinger/tests/utils/TransactionUtils.h
@@ -16,6 +16,9 @@
 
 #pragma once
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
 #include <chrono>
 
 #include <android/native_window.h>
@@ -181,3 +184,6 @@
 };
 } // namespace
 } // namespace android
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop // ignored "-Wconversion"
\ No newline at end of file