Merge "gralloc: Modify check for uncompressed RGB buffers"
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
index 8f77c66..43887e0 100644
--- a/libqdutils/display_config.cpp
+++ b/libqdutils/display_config.cpp
@@ -300,6 +300,41 @@
     return err;
 }
 
+int setPanelBrightness(int level) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+
+    if(binder != NULL) {
+        inParcel.writeInt32(level);
+        status_t err = binder->dispatch(IQService::SET_PANEL_BRIGHTNESS,
+                &inParcel, &outParcel);
+        if(err) {
+            ALOGE("%s() failed with err %d", __FUNCTION__, err);
+        }
+    }
+    return err;
+}
+
+int getPanelBrightness() {
+    int panel_brightness = -1;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+
+    if(binder != NULL) {
+        status_t err = binder->dispatch(IQService::GET_PANEL_BRIGHTNESS,
+                &inParcel, &outParcel);
+        if(!err) {
+            panel_brightness = outParcel.readInt32();
+            ALOGI("%s() Current panel brightness value %d", __FUNCTION__,
+                    panel_brightness);
+        } else {
+            ALOGE("%s() failed with err %d", __FUNCTION__, err);
+        }
+    }
+    return panel_brightness;
+}
+
 }// namespace
 
 // ----------------------------------------------------------------------------
diff --git a/libqdutils/display_config.h b/libqdutils/display_config.h
index b6232ca..8e3fa78 100644
--- a/libqdutils/display_config.h
+++ b/libqdutils/display_config.h
@@ -145,6 +145,12 @@
 // Only HDMI display is supported as dpy for now
 int minHdcpEncryptionLevelChanged(int dpy);
 
+// Sets the panel brightness of the primary display
+int setPanelBrightness(int level);
+
+// Retrieves the current panel brightness value
+int getPanelBrightness();
+
 }; //namespace
 
 #endif
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index df8e235..422ddb2 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -40,8 +40,8 @@
     DECLARE_META_INTERFACE(QService);
     enum {
         COMMAND_LIST_START = android::IBinder::FIRST_CALL_TRANSACTION,
-        SECURING = 2,           // Hardware securing start/end notification
-        UNSECURING = 3,         // Hardware unsecuring start/end notification
+        GET_PANEL_BRIGHTNESS = 2, // Provides ability to set the panel brightness
+        SET_PANEL_BRIGHTNESS = 3, // Provides ability to get the panel brightness
         CONNECT_HWC_CLIENT = 4, // Connect to qservice
         SCREEN_REFRESH = 5,     // Refresh screen through SF invalidate
         EXTERNAL_ORIENTATION = 6,// Set external orientation
@@ -59,7 +59,7 @@
         /* Enable/Disable/Set refresh rate dynamically */
         CONFIGURE_DYN_REFRESH_RATE = 18,
         CONTROL_PARTIAL_UPDATE = 19,   // Provides ability to enable/disable partial update
-        CONTROL_BACKLIGHT = 20, // Provides ability to control backlight
+        TOGGLE_SCREEN_UPDATES = 20, // Provides ability to set the panel brightness
         SET_FRAME_DUMP_CONFIG = 21,  // Provides ability to set the frame dump config
         SET_S3D_MODE = 22, // Set the 3D mode as specified in msm_hdmi_modes.h
         CONNECT_HDMI_CLIENT = 23,  // Connect HDMI CEC HAL Client
diff --git a/libqservice/QServiceUtils.h b/libqservice/QServiceUtils.h
index fbad484..73b2b18 100644
--- a/libqservice/QServiceUtils.h
+++ b/libqservice/QServiceUtils.h
@@ -62,21 +62,12 @@
 // ----------------------------------------------------------------------------
 // Convenience wrappers that clients can call
 // ----------------------------------------------------------------------------
-inline android::status_t securing(uint32_t startEnd) {
-    return sendSingleParam(qService::IQService::SECURING, startEnd);
-}
-
-inline android::status_t unsecuring(uint32_t startEnd) {
-    return sendSingleParam(qService::IQService::UNSECURING, startEnd);
-}
-
 inline android::status_t screenRefresh() {
     return sendSingleParam(qService::IQService::SCREEN_REFRESH, 1);
 }
 
-// TODO(user): Need to rename this wrapper name
 inline android::status_t toggleScreenUpdate(uint32_t on) {
-    return sendSingleParam(qService::IQService::CONTROL_BACKLIGHT, on);
+    return sendSingleParam(qService::IQService::TOGGLE_SCREEN_UPDATES, on);
 }
 
 inline android::status_t setExtOrientation(uint32_t orientation) {
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index be765e5..01037b4 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -408,6 +408,14 @@
   */
   virtual DisplayError SetCursorPosition(int x, int y) = 0;
 
+  /*! @brief Method to get the brightness level of the display
+
+    @param[out] level brightness level
+
+    @return \link DisplayError \endlink
+  */
+  virtual DisplayError GetPanelBrightness(int *level) = 0;
+
  protected:
   virtual ~DisplayInterface() { }
 };
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index f7ec710..4046ce5 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -686,4 +686,8 @@
   return error;
 }
 
+DisplayError DisplayBase::GetPanelBrightness(int *level) {
+  return kErrorNotSupported;
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 4bcb1c4..2f2c072 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -72,7 +72,7 @@
   virtual DisplayError ApplyDefaultDisplayMode(void);
   virtual DisplayError SetCursorPosition(int x, int y);
   virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
-
+  virtual DisplayError GetPanelBrightness(int *level);
 
  protected:
   // DumpImpl method
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index 6aa4ae0..1a00da4 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -331,5 +331,10 @@
   comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
 }
 
+DisplayError DisplayPrimary::GetPanelBrightness(int *level) {
+  SCOPE_LOCK(locker_);
+  return hw_intf_->GetPanelBrightness(level);
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index 0180e72..900939d 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -61,6 +61,7 @@
   virtual DisplayError SetPanelBrightness(int level);
   virtual void AppendDump(char *buffer, uint32_t length);
   virtual DisplayError SetCursorPosition(int x, int y);
+  virtual DisplayError GetPanelBrightness(int *level);
 
   // Implement the HWEventHandlers
   virtual DisplayError VSync(int64_t timestamp);
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index e350254..672e8e7 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -1025,5 +1025,9 @@
   return kErrorNotSupported;
 }
 
+DisplayError HWDevice::GetPanelBrightness(int *level) {
+  return kErrorNotSupported;
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index da43441..cde3efa 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -71,6 +71,7 @@
   virtual DisplayError GetMaxCEAFormat(uint32_t *max_cea_format);
   virtual DisplayError SetCursorPosition(HWLayers *hw_layers, int x, int y);
   virtual DisplayError OnMinHdcpEncryptionLevelChange();
+  virtual DisplayError GetPanelBrightness(int *level);
 
   // For HWDevice derivatives
   virtual DisplayError Init(HWEventHandler *eventhandler);
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index 5e0e1a4..3c308d7 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -610,31 +610,56 @@
 }
 
 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);
+  char buffer[MAX_SYSFS_COMMAND_LENGTH] = {0};
 
   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;
+  int fd = Sys::open_(kBrightnessNode, O_RDWR);
+  if (fd < 0) {
+    DLOGV_IF(kTagDriverConfig, "Failed to open node = %s, error = %s ", kBrightnessNode,
+             strerror(errno));
+    return kErrorFileDescriptor;
   }
-  bytes = snprintf(buffer, MAX_SYSFS_COMMAND_LENGTH, "%d\n", level);
+
+  int32_t 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;
+    DLOGV_IF(kTagDriverConfig, "Failed to copy new brightness level = %d", level);
+    Sys::close_(fd);
+    return kErrorUndefined;
   }
-  ret = Sys::pwrite_(bl_fd, buffer, bytes, 0);
+
+  ssize_t ret = Sys::pwrite_(fd, buffer, bytes, 0);
   if (ret <= 0) {
-    DLOGE("SetPanelBrightness: write failed out :( %d", level);
-    Sys::close_(bl_fd);
+    DLOGV_IF(kTagDriverConfig, "Failed to write to node = %s, error = %s ", kBrightnessNode,
+             strerror(errno));
+    Sys::close_(fd);
+    return kErrorUndefined;
+  }
+  Sys::close_(fd);
+
+  return kErrorNone;
+}
+
+DisplayError HWPrimary::GetPanelBrightness(int *level) {
+  char brightness[kMaxStringLength] = {0};
+
+  if (!level) {
+    DLOGV_IF(kTagDriverConfig, "Invalid input, null pointer.");
     return kErrorParameters;
   }
-  Sys::close_(bl_fd);
+
+  int fd = Sys::open_(kBrightnessNode, O_RDWR);
+  if (fd < 0) {
+    DLOGV_IF(kTagDriverConfig, "Failed to open brightness node = %s, error = %s", kBrightnessNode,
+             strerror(errno));
+    return kErrorFileDescriptor;
+  }
+
+  if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
+    *level = atoi(brightness);
+    DLOGV_IF(kTagDriverConfig, "Brightness level = %d", *level);
+  }
+  Sys::close_(fd);
+
   return kErrorNone;
 }
 
diff --git a/sdm/libs/core/fb/hw_primary.h b/sdm/libs/core/fb/hw_primary.h
index 1aadaf5..b0507c6 100644
--- a/sdm/libs/core/fb/hw_primary.h
+++ b/sdm/libs/core/fb/hw_primary.h
@@ -62,6 +62,7 @@
   virtual DisplayError SetPanelBrightness(int level);
   virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
   virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
+  virtual DisplayError GetPanelBrightness(int *level);
 
  private:
   // Panel modes for the MSMFB_LPM_ENABLE ioctl
@@ -92,6 +93,7 @@
   std::vector<DisplayConfigVariableInfo> display_configs_;
   std::vector<std::string> display_config_strings_;
   uint32_t active_config_index_ = 0;
+  const char *kBrightnessNode = "/sys/class/leds/lcd-backlight/brightness";
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
index c6e3e50..648c313 100644
--- a/sdm/libs/core/hw_interface.h
+++ b/sdm/libs/core/hw_interface.h
@@ -89,6 +89,7 @@
   virtual DisplayError GetMaxCEAFormat(uint32_t *max_cea_format) = 0;
   virtual DisplayError SetCursorPosition(HWLayers *hw_layers, int x, int y) = 0;
   virtual DisplayError OnMinHdcpEncryptionLevelChange() = 0;
+  virtual DisplayError GetPanelBrightness(int *level) = 0;
 
  protected:
   virtual ~HWInterface() { }
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index 09aa779..413db19 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -1275,6 +1275,15 @@
   return ret;
 }
 
+int HWCDisplay::GetPanelBrightness(int *level) {
+  return display_intf_->GetPanelBrightness(level);
+}
+
+int HWCDisplay::ToggleScreenUpdates(bool enable) {
+  display_paused_ = enable ? false : true;
+  return 0;
+}
+
 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 74cdc46..15e62f3 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -71,6 +71,8 @@
   virtual int GetDisplayAttributesForConfig(int config, DisplayConfigVariableInfo *attributes);
 
   int SetPanelBrightness(int level);
+  int GetPanelBrightness(int *level);
+  int ToggleScreenUpdates(bool enable);
   int ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
                            PPDisplayAPIPayload *out_payload,
                            PPPendingParams *pending_action);
diff --git a/sdm/libs/hwc/hwc_display_primary.cpp b/sdm/libs/hwc/hwc_display_primary.cpp
index 3b4c9da..115af3e 100644
--- a/sdm/libs/hwc/hwc_display_primary.cpp
+++ b/sdm/libs/hwc/hwc_display_primary.cpp
@@ -116,6 +116,11 @@
   if (!boot_animation_completed_)
     ProcessBootAnimCompleted();
 
+  if (display_paused_) {
+    MarkLayersForGPUBypass(content_list);
+    return status;
+  }
+
   status = AllocateLayerStack(content_list);
   if (status) {
     return status;
@@ -153,6 +158,22 @@
 
 int HWCDisplayPrimary::Commit(hwc_display_contents_1_t *content_list) {
   int status = 0;
+  if (display_paused_) {
+    if (content_list->outbufAcquireFenceFd >= 0) {
+      // If we do not handle the frame set retireFenceFd to outbufAcquireFenceFd,
+      // which will make sure the framework waits on it and closes it.
+      content_list->retireFenceFd = dup(content_list->outbufAcquireFenceFd);
+      close(content_list->outbufAcquireFenceFd);
+      content_list->outbufAcquireFenceFd = -1;
+    }
+    CloseAcquireFences(content_list);
+
+    DisplayError error = display_intf_->Flush();
+    if (error != kErrorNone) {
+      DLOGE("Flush failed. Error = %d", error);
+    }
+    return status;
+  }
 
   status = HWCDisplay::CommitLayerStack(content_list);
   if (status) {
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index 4090705..98444e1 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -570,8 +570,8 @@
   case qService::IQService::SET_VIEW_FRAME:
     break;
 
-  case qService::IQService::CONTROL_BACKLIGHT:
-    status = ControlBackLight(input_parcel);
+  case qService::IQService::TOGGLE_SCREEN_UPDATES:
+    status = ToggleScreenUpdates(input_parcel, output_parcel);
     break;
 
   case qService::IQService::QDCM_SVC_CMDS:
@@ -602,6 +602,14 @@
     status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
     break;
 
+  case qService::IQService::GET_PANEL_BRIGHTNESS:
+    status = GetPanelBrightness(input_parcel, output_parcel);
+    break;
+
+  case qService::IQService::SET_PANEL_BRIGHTNESS:
+    status = SetPanelBrightness(input_parcel, output_parcel);
+    break;
+
   default:
     DLOGW("QService command = %d is not supported", command);
     return -EINVAL;
@@ -610,43 +618,53 @@
   return status;
 }
 
-android::status_t HWCSession::ControlBackLight(const android::Parcel *input_parcel) {
-  uint32_t display_status = UINT32(input_parcel->readInt32());
-  HWCDisplay *display = hwc_display_[HWC_DISPLAY_PRIMARY];
+android::status_t HWCSession::ToggleScreenUpdates(const android::Parcel *input_parcel,
+                                                  android::Parcel *output_parcel) {
+  int input = input_parcel->readInt32();
+  int error = android::BAD_VALUE;
 
-  DLOGI("Primary Display display_status = %d", display_status);
-
-  int fd = open("/sys/class/leds/lcd-backlight/brightness", O_RDWR);
-  const char *bl_brightness = "0";
-
-  if (fd < 0) {
-    DLOGE("unable to open brightness node err = %d errstr = %s", errno, strerror(errno));
-    return -1;
-  }
-
-  if (display_status == 0) {
-    // Read backlight and store it internally. Set backlight to 0 on primary.
-    if (read(fd, brightness_, sizeof(brightness_)) > 0) {
-      DLOGI("backlight brightness is %s", brightness_);
-      ssize_t ret = write(fd, bl_brightness, strlen(bl_brightness));
-      if (ret < 0) {
-        DLOGE("Failed to write backlight node err = %d errstr = %s", errno, strerror(errno));
-        close(fd);
-        return -1;
-      }
-    }
-  } else {
-    // Restore backlight to original value.
-    ssize_t ret = write(fd, brightness_, sizeof(brightness_));
-    if (ret < 0) {
-      DLOGE("Failed to write backlight node err = %d errstr = %s", errno, strerror(errno));
-      close(fd);
-      return -1;
+  if (hwc_display_[HWC_DISPLAY_PRIMARY] && (input <= 1) && (input >= 0)) {
+    error = hwc_display_[HWC_DISPLAY_PRIMARY]->ToggleScreenUpdates(input == 1);
+    if (error != 0) {
+      DLOGE("Failed to toggle screen updates = %d. Error = %d", input, error);
     }
   }
-  close(fd);
+  output_parcel->writeInt32(error);
 
-  return display->SetDisplayStatus(display_status);
+  return error;
+}
+
+android::status_t HWCSession::SetPanelBrightness(const android::Parcel *input_parcel,
+                                                 android::Parcel *output_parcel) {
+  int level = input_parcel->readInt32();
+  int error = android::BAD_VALUE;
+
+  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+    error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(level);
+    if (error != 0) {
+      DLOGE("Failed to set the panel brightness = %d. Error = %d", level, error);
+    }
+  }
+  output_parcel->writeInt32(error);
+
+  return error;
+}
+
+android::status_t HWCSession::GetPanelBrightness(const android::Parcel *input_parcel,
+                                                 android::Parcel *output_parcel) {
+  int error = android::BAD_VALUE;
+  int ret = error;
+
+  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+    error = hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelBrightness(&ret);
+    if (error != 0) {
+      ret = error;
+      DLOGE("Failed to get the panel brightness. Error = %d", error);
+    }
+  }
+  output_parcel->writeInt32(ret);
+
+  return error;
 }
 
 android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel,
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
index e61e22d..22574dc 100644
--- a/sdm/libs/hwc/hwc_session.h
+++ b/sdm/libs/hwc/hwc_session.h
@@ -91,13 +91,18 @@
   android::status_t SetMaxMixerStages(const android::Parcel *input_parcel);
   android::status_t SetDisplayMode(const android::Parcel *input_parcel);
   android::status_t SetSecondaryDisplayStatus(const android::Parcel *input_parcel);
-  android::status_t ControlBackLight(const android::Parcel *input_parcel);
+  android::status_t ToggleScreenUpdates(const android::Parcel *input_parcel,
+                                        android::Parcel *output_parcel);
   android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
   android::status_t QdcmCMDHandler(const android::Parcel *input_parcel,
                                    android::Parcel *output_parcel);
   android::status_t ControlPartialUpdate(const android::Parcel *input_parcel, android::Parcel *out);
   android::status_t OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
-                                   android::Parcel *output_parcel);
+                                                   android::Parcel *output_parcel);
+  android::status_t SetPanelBrightness(const android::Parcel *input_parcel,
+                                       android::Parcel *output_parcel);
+  android::status_t GetPanelBrightness(const android::Parcel *input_parcel,
+                                       android::Parcel *output_parcel);
   // These functions return the actual display config info as opposed to FB
   android::status_t HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
                                                  android::Parcel *output_parcel);
@@ -119,7 +124,6 @@
   HWCBufferAllocator *buffer_allocator_ = NULL;
   HWCBufferSyncHandler *buffer_sync_handler_ = NULL;
   HWCColorManager *color_mgr_ = NULL;
-  char brightness_[64] = { 0 };
   static bool reset_panel_;
   bool secure_display_active_ = false;
 };