Merge "sdm: Always apply color mode"
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 49467db..d25a06d 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -73,6 +73,7 @@
         MIN_HDCP_ENCRYPTION_LEVEL_CHANGED = 31,
         GET_BW_TRANSACTION_STATUS = 32, //Client can query BW transaction status.
         SET_LAYER_MIXER_RESOLUTION = 33, // Enables client to set layer mixer resolution.
+        SET_COLOR_MODE = 34, // Overrides the QDCM mode on the display
         COMMAND_LIST_END = 400,
     };
 
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 00ef22f..1f0bd55 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -76,7 +76,7 @@
 }
 
 HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes,
-                                        int32_t /*android_color_mode_t*/ *out_modes) {
+                                        android_color_mode_t *out_modes) {
   auto it = color_mode_transform_map_.begin();
   for (auto i = 0; it != color_mode_transform_map_.end(); it++, i++) {
     out_modes[i] = it->first;
@@ -86,7 +86,7 @@
   return HWC2::Error::None;
 }
 
-HWC2::Error HWCColorMode::SetColorMode(int32_t /*android_color_mode_t*/ mode) {
+HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) {
   // first mode in 2D matrix is the mode (identity)
   auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_);
   if (status != HWC2::Error::None) {
@@ -112,7 +112,7 @@
   return status;
 }
 
-HWC2::Error HWCColorMode::HandleColorModeTransform(int32_t /*android_color_mode_t*/ mode,
+HWC2::Error HWCColorMode::HandleColorModeTransform(android_color_mode_t mode,
                                                    android_color_transform_t hint,
                                                    const double *matrix) {
   android_color_transform_t transform_hint = hint;
@@ -165,7 +165,7 @@
   DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
   if (error != kErrorNone || (color_mode_count == 0)) {
     DLOGW("GetColorModeCount failed, use native color mode");
-    PopulateTransform(0, "native_identity");
+    PopulateTransform(HAL_COLOR_MODE_NATIVE, "native_identity");
     return;
   }
 
@@ -177,24 +177,24 @@
   for (uint32_t i = 0; i < color_mode_count; i++) {
     std::string &mode_string = color_modes.at(i);
     DLOGI("Color Mode[%d] = %s", i, mode_string.c_str());
-    if (mode_string.find("native") != std::string::npos) {
-      // TODO(user): replace numbers(0,1..) with android_color_mode_t
-      PopulateTransform(0, mode_string);
-    } else if (mode_string.find("srgb") != std::string::npos) {
-      PopulateTransform(1, mode_string);
-    } else if (mode_string.find("adobe") != std::string::npos) {
-      PopulateTransform(2, mode_string);
-    } else if (mode_string.find("dci3") != std::string::npos) {
-      PopulateTransform(3, mode_string);
+    if (mode_string.find("hal_native") != std::string::npos) {
+      PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string);
+    } else if (mode_string.find("hal_srgb") != std::string::npos) {
+      PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string);
+    } else if (mode_string.find("hal_adobe") != std::string::npos) {
+      PopulateTransform(HAL_COLOR_MODE_ADOBE_RGB, mode_string);
+    } else if (mode_string.find("hal_dci_p3") != std::string::npos) {
+      PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string);
     }
   }
 }
 
-void HWCColorMode::PopulateTransform(const int32_t &mode, const std::string &color_transform) {
+void HWCColorMode::PopulateTransform(const android_color_mode_t &mode,
+                                     const std::string &color_transform) {
   // TODO(user): Check the substring from QDCM
   if (color_transform.find("identity") != std::string::npos) {
     color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_transform;
-  } else if (color_transform.find("artitrary") != std::string::npos) {
+  } else if (color_transform.find("arbitrary") != std::string::npos) {
     // no color mode for arbitrary
   } else if (color_transform.find("inverse") != std::string::npos) {
     color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_VALUE_INVERSE] = color_transform;
@@ -511,9 +511,9 @@
   }
 }
 
-HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, int32_t *out_modes) {
+HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) {
   if (out_modes) {
-    out_modes[0] = 0;  // TODO(user): Change to android_color_mode_t
+    out_modes[0] = HAL_COLOR_MODE_NATIVE;
   }
   *out_num_modes = 1;
 
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 69a2dea..277514d 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -55,17 +55,17 @@
   HWC2::Error Init();
   HWC2::Error DeInit();
   uint32_t GetColorModeCount();
-  HWC2::Error GetColorModes(uint32_t *out_num_modes, int32_t /*android_color_mode_t*/ *out_modes);
-  HWC2::Error SetColorMode(int32_t /*android_color_mode_t*/ mode);
+  HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
+  HWC2::Error SetColorMode(android_color_mode_t mode);
   HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
 
  private:
   static const uint32_t kColorTransformMatrixCount = 16;
 
-  HWC2::Error HandleColorModeTransform(int32_t /*android_color_mode_t*/ mode,
+  HWC2::Error HandleColorModeTransform(android_color_mode_t mode,
                                        android_color_transform_t hint, const double *matrix);
   void PopulateColorModes();
-  void PopulateTransform(const int32_t &mode, const std::string &color_mode);
+  void PopulateTransform(const android_color_mode_t &mode, const std::string &color_mode);
   template <class T>
   void CopyColorTransformMatrix(const T *input_matrix, double *output_matrix) {
     for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
@@ -74,11 +74,10 @@
   }
 
   DisplayInterface *display_intf_ = NULL;
-  int32_t current_color_mode_ = 0;  // android_color_mode_t
+  android_color_mode_t current_color_mode_ = HAL_COLOR_MODE_NATIVE;
   android_color_transform_t current_color_transform_ = HAL_COLOR_TRANSFORM_IDENTITY;
   typedef std::map<android_color_transform_t, std::string> TransformMap;
-  // TODO(user): change int32_t to android_color_mode_t when defined
-  std::map<int32_t, TransformMap> color_mode_transform_map_ = {};
+  std::map<android_color_mode_t, TransformMap> color_mode_transform_map_ = {};
   double color_matrix_[kColorTransformMatrixCount] = {0};
 };
 
@@ -142,13 +141,13 @@
   virtual HWC2::Error SetActiveConfig(hwc2_config_t config);
   virtual HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
                                       int32_t dataspace, hwc_region_t damage);
-  virtual HWC2::Error SetColorMode(int32_t /*android_color_mode_t*/ mode) {
+  virtual HWC2::Error SetColorMode(android_color_mode_t mode) {
     return HWC2::Error::Unsupported;
   }
   virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint) {
     return HWC2::Error::Unsupported;
   }
-  virtual HWC2::Error HandleColorModeTransform(int32_t /*android_color_mode_t*/ mode,
+  virtual HWC2::Error HandleColorModeTransform(android_color_mode_t mode,
                                                android_color_transform_t hint,
                                                const double *matrix) {
     return HWC2::Error::Unsupported;
@@ -158,7 +157,7 @@
                                           int32_t *out_value);
   virtual HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
                                              int32_t dataspace);
-  virtual HWC2::Error GetColorModes(uint32_t *outNumModes, int32_t *outModes);
+  virtual HWC2::Error GetColorModes(uint32_t *outNumModes, android_color_mode_t *outModes);
   virtual HWC2::Error GetChangedCompositionTypes(uint32_t *out_num_elements,
                                                  hwc2_layer_t *out_layers, int32_t *out_types);
   virtual HWC2::Error GetDisplayRequests(int32_t *out_display_requests, uint32_t *out_num_elements,
diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp
index bd1cc54..56ff335 100644
--- a/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -232,7 +232,7 @@
 }
 
 HWC2::Error HWCDisplayPrimary::GetColorModes(uint32_t *out_num_modes,
-                                             int32_t /*android_color_mode_t*/ *out_modes) {
+                                             android_color_mode_t *out_modes) {
   if (out_modes == nullptr) {
     *out_num_modes = color_mode_->GetColorModeCount();
   } else {
@@ -242,7 +242,7 @@
   return HWC2::Error::None;
 }
 
-HWC2::Error HWCDisplayPrimary::SetColorMode(int32_t /*android_color_mode_t*/ mode) {
+HWC2::Error HWCDisplayPrimary::SetColorMode(android_color_mode_t mode) {
   auto status = color_mode_->SetColorMode(mode);
   if (status != HWC2::Error::None) {
     DLOGE("failed for mode = %d", mode);
diff --git a/sdm/libs/hwc2/hwc_display_primary.h b/sdm/libs/hwc2/hwc_display_primary.h
index 41b0c9f..32d265e 100644
--- a/sdm/libs/hwc2/hwc_display_primary.h
+++ b/sdm/libs/hwc2/hwc_display_primary.h
@@ -54,8 +54,8 @@
   virtual int Init();
   virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
   virtual HWC2::Error Present(int32_t *out_retire_fence);
-  virtual HWC2::Error GetColorModes(uint32_t *out_num_modes, int32_t *out_modes);
-  virtual HWC2::Error SetColorMode(int32_t /*android_color_mode_t*/ mode);
+  virtual HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
+  virtual HWC2::Error SetColorMode(android_color_mode_t mode);
   virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
   virtual int Perform(uint32_t operation, ...);
   virtual void SetSecureDisplay(bool secure_display_active);
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index e892d26..91e57c5 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -319,7 +319,8 @@
 }
 
 static int32_t GetColorModes(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_num_modes,
-                             int32_t /*android_color_mode_t*/ *out_modes) {
+                             int32_t /*android_color_mode_t*/ *int_out_modes) {
+  auto out_modes = reinterpret_cast<android_color_mode_t *>(int_out_modes);
   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetColorModes, out_num_modes,
                                          out_modes);
 }
@@ -435,7 +436,8 @@
 }
 
 int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
-                                 int32_t /*android_color_mode_t*/ mode) {
+                                 int32_t /*android_color_mode_t*/ int_mode) {
+  auto mode = static_cast<android_color_mode_t>(int_mode);
   SEQUENCE_WAIT_SCOPE_LOCK(locker_);
   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
 }
@@ -843,9 +845,13 @@
       status = GetBWTransactionStatus(input_parcel, output_parcel);
       break;
 
-  case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
-    status = SetMixerResolution(input_parcel);
-    break;
+    case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
+      status = SetMixerResolution(input_parcel);
+      break;
+
+    case qService::IQService::SET_COLOR_MODE:
+      status = SetColorModeOverride(input_parcel);
+      break;
 
     default:
       DLOGW("QService command = %d is not supported", command);
@@ -1210,6 +1216,16 @@
   return 0;
 }
 
+android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
+  auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
+  auto mode = static_cast<android_color_mode_t>(input_parcel->readInt32());
+  auto device = static_cast<hwc2_device_t *>(this);
+  auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
+  if (err != HWC2_ERROR_NONE)
+    return -EINVAL;
+  return 0;
+}
+
 void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
   int type = input_parcel->readInt32();
   bool enable = (input_parcel->readInt32() > 0);
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 63cce84..6af9da5 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -102,7 +102,7 @@
   static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
                                  uint32_t *out_num_types, uint32_t *out_num_requests);
   static int32_t SetColorMode(hwc2_device_t *device, hwc2_display_t display,
-                              int32_t /*android_color_mode_t*/ mode);
+                              int32_t /*android_color_mode_t*/ int_mode);
   static int32_t SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
                                    const float *matrix, int32_t /*android_color_transform_t*/ hint);
 
@@ -166,6 +166,8 @@
                                            android::Parcel *output_parcel);
   android::status_t SetMixerResolution(const android::Parcel *input_parcel);
 
+  android::status_t SetColorModeOverride(const android::Parcel *input_parcel);
+
   static Locker locker_;
   CoreInterface *core_intf_ = NULL;
   HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {NULL};