Add support for multiple color modes

Bug: 29044347
Change-Id: Iea048eaa62f072a9bbefc4f3a6c29a9e593eab69
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 2629794..133e5f1 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -359,6 +359,27 @@
     return config;
 }
 
+std::vector<int32_t> HWComposer::getColorModes(int32_t displayId) const {
+    std::vector<int32_t> modes;
+
+    if (!isValidDisplay(displayId)) {
+        ALOGE("getColorModes: Attempted to access invalid display %d",
+                displayId);
+        return modes;
+    }
+    const std::shared_ptr<HWC2::Display>& hwcDisplay =
+            mDisplayData[displayId].hwcDisplay;
+
+    auto error = hwcDisplay->getColorModes(&modes);
+    if (error != HWC2::Error::None) {
+        ALOGE("getColorModes failed for display %d: %s (%d)", displayId,
+                to_string(error).c_str(), static_cast<int32_t>(error));
+        return std::vector<int32_t>();
+    }
+
+    return modes;
+}
+
 void HWComposer::setVsyncEnabled(int32_t disp, HWC2::Vsync enabled) {
     if (disp < 0 || disp >= HWC_DISPLAY_VIRTUAL) {
         ALOGD("setVsyncEnabled: Ignoring for virtual display %d", disp);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 1a2a153..aa233df 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -149,6 +149,8 @@
     std::shared_ptr<const HWC2::Display::Config>
             getActiveConfig(int32_t displayId) const;
 
+    std::vector<int32_t> getColorModes(int32_t displayId) const;
+
     // for debugging ----------------------------------------------------------
     void dump(String8& out) const;
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e156e1a..5c7db2b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -614,9 +614,6 @@
         info.fps = 1e9 / hwConfig->getVsyncPeriod();
         info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
 
-        // TODO: Hook this back up
-        info.colorTransform = 0;
-
         // This is how far in advance a buffer must be queued for
         // presentation at a given time.  If you want a buffer to appear
         // on the screen at time N, you must submit the buffer before
@@ -635,7 +632,18 @@
         // All non-virtual displays are currently considered secure.
         info.secure = true;
 
-        configs->push_back(info);
+        // DisplayManager expects each color mode to be its own display
+        // info record.
+        std::vector<int32_t> modes = getHwComposer().getColorModes(type);
+
+        if (modes.size() == 0) {
+            info.colorTransform = 0;
+            configs->push_back(info);
+        }
+        for (int32_t mode : modes) {
+            info.colorTransform = mode;
+            configs->push_back(info);
+        }
     }
 
     return NO_ERROR;