[SurfaceFlinger] Add opcode to change composition data space.

We want to keep experimenting/measuring the effect of switching to wider color
gamut as default gamut and/or wide color gamut. To provide composition data
space overwrite, we expose opcode 1031 for composition data space overwrite.

BUG: 111436479
Test: Build, flash, and boot
Test: adb shell service call SurfaceFlinger 1031 i32 1 0 142671872 && \
      adb shell stop zygote && adb shell start zygote
Change-Id: I35f9b0fcc73348f7805d2f5968037cb1c578755a
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index dec08fd..a1a8e22 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -173,6 +173,11 @@
     bool mLocked;
 };
 
+// Currently we only support V0_SRGB and DISPLAY_P3 as composition preference.
+bool validateCompositionDataspace(Dataspace dataspace) {
+    return dataspace == Dataspace::V0_SRGB || dataspace == Dataspace::DISPLAY_P3;
+}
+
 }  // namespace anonymous
 
 // ---------------------------------------------------------------------------
@@ -191,7 +196,6 @@
 bool SurfaceFlinger::hasSyncFramework;
 bool SurfaceFlinger::useVrFlinger;
 int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
-// TODO(courtneygo): Rename hasWideColorDisplay to clarify its actual meaning.
 bool SurfaceFlinger::hasWideColorDisplay;
 int SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientationDefault;
 bool SurfaceFlinger::useColorManagement;
@@ -313,6 +317,8 @@
                     wideColorGamutCompositionPixelFormat = tmpWideColorGamutPixelFormat;
                 });
     }
+    mDefaultCompositionDataspace = defaultCompositionDataspace;
+    mWideColorGamutCompositionDataspace = wideColorGamutCompositionDataspace;
 
     useContextPriority = getBool<ISurfaceFlingerConfigs,
                                  &ISurfaceFlingerConfigs::useContextPriority>(true);
@@ -1170,9 +1176,9 @@
         Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
         Dataspace* outWideColorGamutDataspace,
         ui::PixelFormat* outWideColorGamutPixelFormat) const {
-    *outDataspace = defaultCompositionDataspace;
+    *outDataspace = mDefaultCompositionDataspace;
     *outPixelFormat = defaultCompositionPixelFormat;
-    *outWideColorGamutDataspace = wideColorGamutCompositionDataspace;
+    *outWideColorGamutDataspace = mWideColorGamutCompositionDataspace;
     *outWideColorGamutPixelFormat = wideColorGamutCompositionPixelFormat;
     return NO_ERROR;
 }
@@ -4746,9 +4752,9 @@
         code == IBinder::SYSPROPS_TRANSACTION) {
         return OK;
     }
-    // Numbers from 1000 to 1030 are currently use for backdoors. The code
+    // Numbers from 1000 to 1031 are currently use for backdoors. The code
     // in onTransact verifies that the user is root, and has access to use SF.
-    if (code >= 1000 && code <= 1030) {
+    if (code >= 1000 && code <= 1031) {
         ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);
         return OK;
     }
@@ -5002,6 +5008,38 @@
                 reply->writeBool(useColorManagement);
                 return NO_ERROR;
             }
+            // Override default composition data space
+            // adb shell service call SurfaceFlinger 1031 i32 1 DATASPACE_NUMBER DATASPACE_NUMBER \
+            // && adb shell stop zygote && adb shell start zygote
+            // to restore: adb shell service call SurfaceFlinger 1031 i32 0 && \
+            // adb shell stop zygote && adb shell start zygote
+            case 1031: {
+                Mutex::Autolock _l(mStateLock);
+                n = data.readInt32();
+                if (n) {
+                    n = data.readInt32();
+                    if (n) {
+                        Dataspace dataspace = static_cast<Dataspace>(n);
+                        if (!validateCompositionDataspace(dataspace)) {
+                            return BAD_VALUE;
+                        }
+                        mDefaultCompositionDataspace = dataspace;
+                    }
+                    n = data.readInt32();
+                    if (n) {
+                        Dataspace dataspace = static_cast<Dataspace>(n);
+                        if (!validateCompositionDataspace(dataspace)) {
+                            return BAD_VALUE;
+                        }
+                        mWideColorGamutCompositionDataspace = dataspace;
+                    }
+                } else {
+                    // restore composition data space.
+                    mDefaultCompositionDataspace = defaultCompositionDataspace;
+                    mWideColorGamutCompositionDataspace = wideColorGamutCompositionDataspace;
+                }
+                return NO_ERROR;
+            }
         }
     }
     return err;