sdm: Add set panel brightness to be used by color manager

QDCM color manager needs some way to set panel brightness. This change
exposes set panel brightness api.

Change-Id: I8a13cd0b0d1a915b06b0dedad2041a8eec7806ed
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 37d3b32..40ef738 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -356,6 +356,14 @@
   */
   virtual bool IsUnderscanSupported() = 0;
 
+  /*! @brief Method to set brightness of the primary display.
+
+    @param[in] level the new backlight level.
+
+    @return \link DisplayError \endlink
+  */
+  virtual DisplayError SetPanelBrightness(int level) = 0;
+
   /*! @brief Method to route display API requests to color service.
 
     @param[in] in_payload \link PPDisplayAPIPayload \endlink
diff --git a/sdm/include/private/color_params.h b/sdm/include/private/color_params.h
index ffc28ff..a3387d3 100644
--- a/sdm/include/private/color_params.h
+++ b/sdm/include/private/color_params.h
@@ -46,6 +46,7 @@
   kDisableSolidFill = BITMAP(2),
   kEnterQDCMMode = BITMAP(3),
   kExitQDCMMode = BITMAP(4),
+  kSetPanelBrightness = BITMAP(5),
   kNoAction = BITMAP(31),
 };
 
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 8e91e3d..b0c933c 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -440,6 +440,10 @@
   return comp_manager_->ValidateScaling(crop, dst, rotate90);
 }
 
+DisplayError DisplayBase::SetPanelBrightness(int level) {
+  return kErrorNotSupported;
+}
+
 void DisplayBase::AppendDump(char *buffer, uint32_t length) {
   DumpImpl::AppendString(buffer, length, "\n-----------------------");
   DumpImpl::AppendString(buffer, length, "\ndevice type: %u", display_type_);
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index f8704bf..531217e 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -64,6 +64,7 @@
   virtual DisplayError SetDisplayMode(uint32_t mode);
   virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
   virtual bool IsUnderscanSupported();
+  virtual DisplayError SetPanelBrightness(int level);
   virtual DisplayError ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
                                             PPDisplayAPIPayload *out_payload,
                                             PPPendingParams *pending_action);
diff --git a/sdm/libs/core/display_hdmi.cpp b/sdm/libs/core/display_hdmi.cpp
index a5a35a5..20a1524 100644
--- a/sdm/libs/core/display_hdmi.cpp
+++ b/sdm/libs/core/display_hdmi.cpp
@@ -171,6 +171,11 @@
   return DisplayBase::IsUnderscanSupported();
 }
 
+DisplayError DisplayHDMI::SetPanelBrightness(int level) {
+  SCOPE_LOCK(locker_);
+  return DisplayBase::SetPanelBrightness(level);
+}
+
 int DisplayHDMI::GetBestConfig() {
   uint32_t best_config_mode = 0;
   HWDisplayAttributes *best = &display_attributes_[0];
diff --git a/sdm/libs/core/display_hdmi.h b/sdm/libs/core/display_hdmi.h
index fb07466..e247eb7 100644
--- a/sdm/libs/core/display_hdmi.h
+++ b/sdm/libs/core/display_hdmi.h
@@ -58,6 +58,7 @@
   virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
   virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
   virtual bool IsUnderscanSupported();
+  virtual DisplayError SetPanelBrightness(int level);
   virtual void AppendDump(char *buffer, uint32_t length);
 
  private:
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index dd1beed..40d8817 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -237,6 +237,10 @@
 
   return error;
 }
+DisplayError DisplayPrimary::SetPanelBrightness(int level) {
+  SCOPE_LOCK(locker_);
+  return hw_primary_intf_->SetPanelBrightness(level);
+}
 
 DisplayError DisplayPrimary::IsScalingValid(const LayerRect &crop, const LayerRect &dst,
                                             bool rotate90) {
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index b232d89..f793984 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -58,6 +58,7 @@
   virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
   virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
   virtual bool IsUnderscanSupported();
+  virtual DisplayError SetPanelBrightness(int level);
   virtual void AppendDump(char *buffer, uint32_t length);
 
   // Implement the HWEventHandlers
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index f01ff58..3115137 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -194,6 +194,11 @@
   return kErrorNotSupported;
 }
 
+DisplayError DisplayVirtual::SetPanelBrightness(int level) {
+  SCOPE_LOCK(locker_);
+  return DisplayBase::SetPanelBrightness(level);
+}
+
 void DisplayVirtual::AppendDump(char *buffer, uint32_t length) {
   SCOPE_LOCK(locker_);
   DisplayBase::AppendDump(buffer, length);
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index 6152f69..4021124 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -58,6 +58,7 @@
   virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
   virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
   virtual bool IsUnderscanSupported();
+  virtual DisplayError SetPanelBrightness(int level);
   virtual void AppendDump(char *buffer, uint32_t length);
 
  private:
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index f4381b5..d7fb290 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -500,6 +500,35 @@
   return kErrorNone;
 }
 
+DisplayError HWPrimary::SetPanelBrightness(int level) {
+  char buffer[MAX_SYSFS_COMMAND_LENGTH];
+  int32_t bytes, bl_fd = -1;
+  ssize_t ret;
+
+  memset(buffer, 0, MAX_SYSFS_COMMAND_LENGTH);
+
+  DLOGV_IF(kTagDriverConfig, "Set brightness level to %d", level);
+  bl_fd = Sys::open_("/sys/class/leds/lcd-backlight/brightness", O_RDWR);
+  if (bl_fd < 0) {
+    DLOGI("SetPanelBrightness: open failed out :( %d", level);
+    return kErrorParameters;
+  }
+  bytes = snprintf(buffer, MAX_SYSFS_COMMAND_LENGTH, "%d\n", level);
+  if (bytes < 0) {
+    DLOGE("SetPanelBrightness: snprintf failed out :( %d", level);
+    Sys::close_(bl_fd);
+    return kErrorParameters;
+  }
+  ret = Sys::pwrite_(bl_fd, buffer, bytes, 0);
+  if (ret <= 0) {
+    DLOGE("SetPanelBrightness: write failed out :( %d", level);
+    Sys::close_(bl_fd);
+    return kErrorParameters;
+  }
+  Sys::close_(bl_fd);
+  return kErrorNone;
+}
+
 DisplayError HWPrimary::GetPPFeaturesVersion(PPFeatureVersion *vers) {
   STRUCT_VAR(mdp_pp_feature_version, version);
 
diff --git a/sdm/libs/core/fb/hw_primary.h b/sdm/libs/core/fb/hw_primary.h
index 001c776..e46a707 100644
--- a/sdm/libs/core/fb/hw_primary.h
+++ b/sdm/libs/core/fb/hw_primary.h
@@ -31,6 +31,7 @@
 #include "hw_primary_interface.h"
 
 namespace sdm {
+#define MAX_SYSFS_COMMAND_LENGTH 12
 
 class HWPrimary : public HWDevice, public HWPrimaryInterface {
  public:
@@ -57,6 +58,7 @@
   virtual DisplayError SetVSyncState(bool enable);
   virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode);
   virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
+  virtual DisplayError SetPanelBrightness(int level);
   virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
   virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
 
diff --git a/sdm/libs/core/hw_primary_interface.h b/sdm/libs/core/hw_primary_interface.h
index 9faa6e5..290f9cb 100644
--- a/sdm/libs/core/hw_primary_interface.h
+++ b/sdm/libs/core/hw_primary_interface.h
@@ -39,6 +39,7 @@
   virtual void SetIdleTimeoutMs(uint32_t timeout_ms) = 0;
   virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode) = 0;
   virtual DisplayError SetRefreshRate(uint32_t refresh_rate) = 0;
+  virtual DisplayError SetPanelBrightness(int level) = 0;
 
  protected:
   virtual ~HWPrimaryInterface() { }
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index 6352a4a..960abf5 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -1216,6 +1216,16 @@
   return kErrorNone;
 }
 
+int HWCDisplay::SetPanelBrightness(int level) {
+  int ret = 0;
+  if (display_intf_)
+    ret = display_intf_->SetPanelBrightness(level);
+  else
+    ret = -EINVAL;
+
+  return ret;
+}
+
 int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
                                      PPDisplayAPIPayload *out_payload,
                                      PPPendingParams *pending_action) {
diff --git a/sdm/libs/hwc/hwc_display.h b/sdm/libs/hwc/hwc_display.h
index 2930cab..b3b5667 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -57,6 +57,7 @@
   virtual int Perform(uint32_t operation, ...);
   virtual ~HWCDisplay() { }
 
+  int SetPanelBrightness(int level);
   int ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
                            PPDisplayAPIPayload *out_payload,
                            PPPendingParams *pending_action);
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index c746936..3b521b1 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -700,6 +700,7 @@
 
 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel &in, android::Parcel *out) {
   int ret = 0;
+  int *brightness_value = NULL;
   uint32_t display_id(0);
   PPPendingParams pending_action;
   PPDisplayAPIPayload resp_payload, req_payload;
@@ -736,6 +737,17 @@
     case kApplySolidFill:
     case kDisableSolidFill:
       break;
+    case kSetPanelBrightness:
+      brightness_value = reinterpret_cast<int*>(pending_action.params);
+      pending_action.params = NULL;
+      if (brightness_value == NULL) {
+        DLOGE("Brightness is null");
+        return -EINVAL;
+      }
+      if (HWC_DISPLAY_PRIMARY == display_id)
+        ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
+      delete brightness_value;
+      break;
     case kNoAction:
       break;
     default: