display: Add API to set luminance

-Add API to set min/max luminance range for given display.
-using API via binder
 adb shell "vndservice call display.qservice 46 i32 <display_id>
 f <min_lum> f <max_lum>"

Change-Id: I97c31b18cac4ab8ac45518833d0964b7e54c9d58
diff --git a/common.mk b/common.mk
index e2f3c4c..eca4769 100644
--- a/common.mk
+++ b/common.mk
@@ -3,8 +3,13 @@
 
 #Get the highest display config version available
 display_config_version := $(shell \
+    if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.9" ];\
+    then echo DISPLAY_CONFIG_1_9; fi)
+ifeq ($(display_config_version),)
+display_config_version := $(shell \
     if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.8" ];\
     then echo DISPLAY_CONFIG_1_8; fi)
+endif
 ifeq ($(display_config_version),)
 display_config_version := $(shell \
     if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.7" ];\
@@ -81,6 +86,11 @@
     common_flags += -DDISPLAY_CONFIG_1_4 -DDISPLAY_CONFIG_1_5 -DDISPLAY_CONFIG_1_6
     common_flags += -DDISPLAY_CONFIG_1_7 -DDISPLAY_CONFIG_1_8
 endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_9)
+    common_flags += -DDISPLAY_CONFIG_1_1 -DDISPLAY_CONFIG_1_2 -DDISPLAY_CONFIG_1_3
+    common_flags += -DDISPLAY_CONFIG_1_4 -DDISPLAY_CONFIG_1_5 -DDISPLAY_CONFIG_1_6
+    common_flags += -DDISPLAY_CONFIG_1_7 -DDISPLAY_CONFIG_1_8 -DDISPLAY_CONFIG_1_9
+endif
 
 ifeq ($(TARGET_USES_COLOR_METADATA), true)
     common_flags += -DUSE_COLOR_METADATA
diff --git a/config/display-product.mk b/config/display-product.mk
index ef2585c..8d165e0 100644
--- a/config/display-product.mk
+++ b/config/display-product.mk
@@ -22,6 +22,7 @@
     vendor.display.config@1.6.vendor \
     vendor.display.config@1.7.vendor \
     vendor.display.config@1.8.vendor \
+    vendor.display.config@1.9.vendor \
     modetest
 
 #QDCM calibration xml file for 2k panel
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
index fc2e3dc..f9e7e33 100644
--- a/libqdutils/display_config.cpp
+++ b/libqdutils/display_config.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2013-2014, 2016, 2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2013-2014, 2016, 2018, 2019, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -370,6 +370,23 @@
     return 0;
 }
 
+int setPanelLuminanceAttributes(int dpy, float min_lum, float max_lum) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+
+    if(binder != NULL) {
+        inParcel.writeInt32(dpy);
+        inParcel.writeFloat(min_lum);
+        inParcel.writeFloat(max_lum);
+        status_t err = binder->dispatch(IQService::SET_PANEL_LUMINANCE, &inParcel, &outParcel);
+        if(err) {
+            ALOGE("%s() failed with err %d", __FUNCTION__, err);
+        }
+    }
+    return err;
+}
+
 }// namespace
 
 // ----------------------------------------------------------------------------
diff --git a/libqdutils/display_config.h b/libqdutils/display_config.h
index c0952b0..ad41ed7 100644
--- a/libqdutils/display_config.h
+++ b/libqdutils/display_config.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 - 2016, 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013 - 2016, 2018, 2019, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -171,6 +171,9 @@
 // Get supported bit clk values.
 int getSupportedBitClk(int dpy, std::vector<uint64_t>& bit_rates);
 
+// Sets the specified min and max luminance values.
+int setPanelLuminanceAttributes(int dpy, float min_lum, float max_lum);
+
 }; //namespace
 
 
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index e19eccc..387eaca 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -85,6 +85,7 @@
         GET_DSI_CLK = 43, // Get DSI Clk.
         GET_SUPPORTED_DSI_CLK = 44, // Get supported DSI Clk.
         SET_COLOR_MODE_FROM_CLIENT = 45, // Overrides the QDCM mode using the given mode ID
+        SET_PANEL_LUMINANCE = 46, // Set Panel Luminance attributes.
         COMMAND_LIST_END = 400,
     };
 
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 922d7ba..bfd4d64 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -837,6 +837,15 @@
   virtual DisplayError GetDisplayIdentificationData(uint8_t *out_port, uint32_t *out_data_size,
                                                     uint8_t *out_data) = 0;
 
+  /*! @brief Method to set min/max luminance for dynamic tonemapping of external device over WFD.
+
+    @param[in] min_lum min luminance supported by external device.
+    @param[in] max_lum max luminance supported by external device.
+
+    @return \link DisplayError \endlink
+  */
+  virtual DisplayError SetPanelLuminanceAttributes(float min_lum, float max_lum) = 0;
+
  protected:
   virtual ~DisplayInterface() { }
 };
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 9039aff..6cdf6ff 100755
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -103,6 +103,9 @@
   virtual DisplayError GetSupportedDSIClock(std::vector<uint64_t> *bitclk_rates) {
     return kErrorNotSupported;
   }
+  virtual DisplayError SetPanelLuminanceAttributes(float min_lum, float max_lum) {
+    return kErrorNotSupported;
+  }
   virtual DisplayError GetColorModeCount(uint32_t *mode_count);
   virtual DisplayError GetColorModes(uint32_t *mode_count, std::vector<std::string> *color_modes);
   virtual DisplayError GetColorModeAttr(const std::string &color_mode, AttrVal *attr);
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index bf53c66..ad7dad6 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -121,6 +121,13 @@
 
   hw_intf_->GetHWPanelInfo(&hw_panel_info);
 
+  if (set_max_lum_ != -1.0 || set_min_lum_ != -1.0) {
+    hw_panel_info.peak_luminance = set_max_lum_;
+    hw_panel_info.blackness_level = set_min_lum_;
+    DLOGI("set peak_luminance %f blackness_level %f", hw_panel_info.peak_luminance,
+          hw_panel_info.blackness_level);
+  }
+
   error = hw_intf_->GetMixerAttributes(&mixer_attributes);
   if (error != kErrorNone) {
     return error;
@@ -174,5 +181,11 @@
   return kErrorNone;
 }
 
+DisplayError DisplayVirtual::SetPanelLuminanceAttributes(float min_lum, float max_lum) {
+  set_max_lum_ = max_lum;
+  set_min_lum_ = min_lum;
+  return kErrorNone;
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index 1a672e1..1ae469c 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2019, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
@@ -52,6 +52,7 @@
   virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height) {
     return kErrorNotSupported;
   }
+  virtual DisplayError SetPanelLuminanceAttributes(float min_lum, float max_lum);
   virtual DisplayError SetVSyncState(bool enable) {
     return kErrorNotSupported;
   }
@@ -71,6 +72,10 @@
   }
   virtual DisplayError TeardownConcurrentWriteback(void) { return kErrorNotSupported; }
   virtual DisplayError GetColorModeCount(uint32_t *mode_count);
+
+ protected:
+  float set_max_lum_ = -1.0;
+  float set_min_lum_ = -1.0;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk
index daca922..78bce5e 100644
--- a/sdm/libs/hwc2/Android.mk
+++ b/sdm/libs/hwc2/Android.mk
@@ -80,6 +80,17 @@
 LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.7
 LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.8
 endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_9)
+LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.1
+LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.2
+LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.3
+LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.4
+LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.5
+LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.6
+LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.7
+LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.8
+LOCAL_SHARED_LIBRARIES        += vendor.display.config@1.9
+endif
 
 ifeq ($(TARGET_BOARD_AUTO), true)
 LOCAL_CFLAGS                  += -DCONFIG_BASEID_FROM_PROP
diff --git a/sdm/libs/hwc2/display_null.h b/sdm/libs/hwc2/display_null.h
index 7d31c6b..4390f4e 100644
--- a/sdm/libs/hwc2/display_null.h
+++ b/sdm/libs/hwc2/display_null.h
@@ -108,6 +108,7 @@
   MAKE_NO_OP(SetDynamicDSIClock(uint64_t bit_clk_rate))
   MAKE_NO_OP(GetDynamicDSIClock(uint64_t *bit_clk_rate))
   MAKE_NO_OP(GetSupportedDSIClock(vector<uint64_t> *bitclk_rates))
+  MAKE_NO_OP(SetPanelLuminanceAttributes(float min_lum, float max_lum))
 
  protected:
   DisplayConfigVariableInfo default_variable_config_ = {};
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index b1951ef..11d2613 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -240,6 +240,9 @@
   virtual HWC2::Error AcceptDisplayChanges(void);
   virtual HWC2::Error GetActiveConfig(hwc2_config_t *out_config);
   virtual HWC2::Error SetActiveConfig(hwc2_config_t config);
+  virtual HWC2::Error SetPanelLuminanceAttributes(float min_lum, float max_lum) {
+    return HWC2::Error::Unsupported;
+  }
   virtual HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
                                       int32_t dataspace, hwc_region_t damage);
   virtual HWC2::Error SetColorMode(ColorMode mode) { return HWC2::Error::Unsupported; }
diff --git a/sdm/libs/hwc2/hwc_display_virtual.cpp b/sdm/libs/hwc2/hwc_display_virtual.cpp
index d58ef2f..6930399 100644
--- a/sdm/libs/hwc2/hwc_display_virtual.cpp
+++ b/sdm/libs/hwc2/hwc_display_virtual.cpp
@@ -42,7 +42,7 @@
 int HWCDisplayVirtual::Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
                               HWCCallbacks *callbacks, hwc2_display_t id, int32_t sdm_id,
                               uint32_t width, uint32_t height, int32_t *format,
-                              HWCDisplay **hwc_display) {
+                              HWCDisplay **hwc_display, float min_lum, float max_lum) {
   int status = 0;
   HWCDisplayVirtual *hwc_display_virtual = new HWCDisplayVirtual(core_intf, buffer_allocator,
                                                                  callbacks, id, sdm_id);
@@ -57,6 +57,10 @@
     return status;
   }
 
+  if (max_lum != -1.0 || min_lum != -1.0) {
+    hwc_display_virtual->SetPanelLuminanceAttributes(min_lum, max_lum);
+  }
+
   status = hwc_display_virtual->SetConfig(width, height);
   if (status) {
     Destroy(hwc_display_virtual);
@@ -214,6 +218,15 @@
   return 0;
 }
 
+
+HWC2::Error HWCDisplayVirtual::SetPanelLuminanceAttributes(float min_lum, float max_lum) {
+  DisplayError err = display_intf_->SetPanelLuminanceAttributes(min_lum, max_lum);
+  if (err != kErrorNone) {
+    return HWC2::Error::BadParameter;
+  }
+  return HWC2::Error::None;
+}
+
 HWC2::Error HWCDisplayVirtual::SetOutputBuffer(buffer_handle_t buf, int32_t release_fence) {
   if (buf == nullptr || release_fence == 0) {
     return HWC2::Error::BadParameter;
diff --git a/sdm/libs/hwc2/hwc_display_virtual.h b/sdm/libs/hwc2/hwc_display_virtual.h
index 6b39775..c325a7f 100644
--- a/sdm/libs/hwc2/hwc_display_virtual.h
+++ b/sdm/libs/hwc2/hwc_display_virtual.h
@@ -41,7 +41,8 @@
  public:
   static int Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
                     HWCCallbacks *callbacks, hwc2_display_t id, int32_t sdm_id, uint32_t width,
-                    uint32_t height, int32_t *format, HWCDisplay **hwc_display);
+                    uint32_t height, int32_t *format, HWCDisplay **hwc_display, float min_lum,
+                    float max_lum);
   static void Destroy(HWCDisplay *hwc_display);
   virtual int Init();
   virtual int Deinit();
@@ -51,6 +52,7 @@
                                          int32_t format, bool post_processed);
   virtual HWC2::Error GetDisplayType(int32_t *out_type);
   virtual HWC2::Error SetColorMode(ColorMode mode);
+  virtual HWC2::Error SetPanelLuminanceAttributes(float min_lum, float max_lum);
   HWC2::Error SetOutputBuffer(buffer_handle_t buf, int32_t release_fence);
 
  private:
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 1c1ea99..674f666 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -1276,7 +1276,8 @@
         }
 
         status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, client_id,
-                                           info.display_id, width, height, format, &hwc_display);
+                                           info.display_id, width, height, format, &hwc_display,
+                                           set_min_lum_, set_max_lum_);
         // TODO(user): validate width and height support
         if (status) {
           return HWC2::Error::NoResources;
@@ -1616,6 +1617,14 @@
       status = GetSupportedDsiClk(input_parcel, output_parcel);
       break;
 
+    case qService::IQService::SET_PANEL_LUMINANCE:
+      if (!input_parcel) {
+        DLOGE("QService command = %d: input_parcel needed.", command);
+        break;
+      }
+      status = SetPanelLuminanceAttributes(input_parcel);
+      break;
+
     case qService::IQService::SET_COLOR_MODE_FROM_CLIENT:
       if (!input_parcel) {
         DLOGE("QService command = %d: input_parcel needed.", command);
@@ -2265,6 +2274,22 @@
   return 0;
 }
 
+android::status_t HWCSession::SetPanelLuminanceAttributes(const android::Parcel *input_parcel) {
+  int disp_id = input_parcel->readInt32();
+
+  // currently doing only for virtual display
+  if (disp_id != qdutils::DISPLAY_VIRTUAL) {
+    return -EINVAL;
+  }
+
+  std::lock_guard<std::mutex> obj(mutex_lum_);
+  set_min_lum_ = input_parcel->readFloat();
+  set_max_lum_ = input_parcel->readFloat();
+  DLOGI("set max_lum %f, min_lum %f", set_max_lum_, set_min_lum_);
+
+  return 0;
+}
+
 void HWCSession::UEventHandler(const char *uevent_data, int length) {
   // Drop hotplug uevents until SurfaceFlinger (the client) is connected. The equivalent of hotplug
   // uevent handling will be done once when SurfaceFlinger connects, at RegisterCallback(). Since
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 1d546cc..a1bd80a 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -20,7 +20,9 @@
 #ifndef __HWC_SESSION_H__
 #define __HWC_SESSION_H__
 
-#ifdef DISPLAY_CONFIG_1_8
+#ifdef DISPLAY_CONFIG_1_9
+#include <vendor/display/config/1.9/IDisplayConfig.h>
+#elif DISPLAY_CONFIG_1_8
 #include <vendor/display/config/1.8/IDisplayConfig.h>
 #elif DISPLAY_CONFIG_1_7
 #include <vendor/display/config/1.7/IDisplayConfig.h>
@@ -61,7 +63,9 @@
 
 namespace sdm {
 
-#ifdef DISPLAY_CONFIG_1_8
+#ifdef DISPLAY_CONFIG_1_9
+using vendor::display::config::V1_9::IDisplayConfig;
+#elif DISPLAY_CONFIG_1_8
 using vendor::display::config::V1_8::IDisplayConfig;
 #elif DISPLAY_CONFIG_1_7
 using vendor::display::config::V1_7::IDisplayConfig;
@@ -351,6 +355,12 @@
   Return<void> getActiveBuiltinDisplayAttributes(getDisplayAttributes_cb _hidl_cb) override;
 #endif
 
+#ifdef DISPLAY_CONFIG_1_9
+  Return<int32_t> setPanelLuminanceAttributes(uint32_t disp_id, float min_lum,
+                                              float max_lum) override;
+  Return<bool> isBuiltInDisplay(uint32_t disp_id) override;
+#endif
+
   // QClient methods
   virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
                                            android::Parcel *output_parcel);
@@ -384,6 +394,7 @@
   android::status_t GetDsiClk(const android::Parcel *input_parcel, android::Parcel *output_parcel);
   android::status_t GetSupportedDsiClk(const android::Parcel *input_parcel,
                                        android::Parcel *output_parcel);
+  android::status_t SetPanelLuminanceAttributes(const android::Parcel *input_parcel);
 
   void Refresh(hwc2_display_t display);
   void HotPlug(hwc2_display_t display, HWC2::Connection state);
@@ -420,6 +431,7 @@
   bool hdmi_is_primary_ = false;
   bool is_composer_up_ = false;
   Locker callbacks_lock_;
+  std::mutex mutex_lum_;
   int hpd_bpp_ = 0;
   int hpd_pattern_ = 0;
   static bool power_on_pending_[HWCCallbacks::kNumDisplays];
@@ -430,6 +442,8 @@
   uint32_t idle_pc_ref_cnt_ = 0;
   int32_t disable_hotplug_bwcheck_ = 0;
   int32_t disable_mask_layer_hint_ = 0;
+  float set_max_lum_ = -1.0;
+  float set_min_lum_ = -1.0;
   std::bitset<HWCCallbacks::kNumDisplays> pending_refresh_;
 };
 
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
index 2a8d631..60786e7 100644
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ b/sdm/libs/hwc2/hwc_session_services.cpp
@@ -766,4 +766,34 @@
 }
 #endif  // DISPLAY_CONFIG_1_8
 
+#ifdef DISPLAY_CONFIG_1_9
+Return<int32_t> HWCSession::setPanelLuminanceAttributes(uint32_t disp_id, float pan_min_lum,
+                                                        float pan_max_lum) {
+  // currently doing only for virtual display
+  if (disp_id != qdutils::DISPLAY_VIRTUAL) {
+    return -EINVAL;
+  }
+
+  std::lock_guard<std::mutex> obj(mutex_lum_);
+  set_min_lum_ = pan_min_lum;
+  set_max_lum_ = pan_max_lum;
+  DLOGI("set max_lum %f, min_lum %f", set_max_lum_, set_min_lum_);
+
+  return 0;
+}
+
+Return<bool> HWCSession::isBuiltInDisplay(uint32_t disp_id) {
+  if ((map_info_primary_.client_id == disp_id) && (map_info_primary_.disp_type == kBuiltIn))
+    return true;
+
+  for (auto &info : map_info_builtin_) {
+    if (disp_id == info.client_id) {
+      return true;
+    }
+  }
+
+  return false;
+}
+#endif  // DISPLAY_CONFIG_1_9
+
 }  // namespace sdm