display: add support for IDisplayConfig 2.0

Change-Id: I7193697b95ea58c5661d3a8782c30ada3813a042
diff --git a/Android.bp b/Android.bp
index 8b6997e..947077e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -6,5 +6,6 @@
         "include",
         "libdisplayconfig",
         "libqdmetadata",
+        "services",
     ],
 }
diff --git a/services/config/client_interface.h b/services/config/client_interface.h
new file mode 100644
index 0000000..faf772a
--- /dev/null
+++ b/services/config/client_interface.h
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2020 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:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __CLIENT_INTERFACE_H__
+#define __CLIENT_INTERFACE_H__
+
+#include "config_defs.h"
+
+namespace DisplayConfig {
+
+class ClientInterface : public ConfigInterface  {
+ public:
+  static int Create(std::string client_name, ConfigCallback *callback,
+                    ClientInterface **intf);
+  static void Destroy(ClientInterface *intf);
+
+ protected:
+  virtual ~ClientInterface() { }
+};
+
+}  // namespace DisplayConfig
+
+#endif  // __CLIENT_INTERFACE_H__
diff --git a/services/config/config_defs.h b/services/config/config_defs.h
new file mode 100644
index 0000000..77eea44
--- /dev/null
+++ b/services/config/config_defs.h
@@ -0,0 +1,291 @@
+/*
+* Copyright (c) 2020 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:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __CONFIG_DEFS_H__
+#define __CONFIG_DEFS_H__
+
+#include <vector>
+#include <string>
+
+// #defines specifying the API level supported
+// Client can use these API level #ifdefs in their implementation to call the
+// corresponding DisplayConfig API independent of the underlying DisplayConfig
+// implementation being present. When this ifdef gets enabled in this header, the
+// client code will automatically get compiled.
+#define DISPLAY_CONFIG_API_LEVEL_0
+
+namespace DisplayConfig {
+
+// enum definitions
+enum class DisplayType : int {
+  kInvalid,
+  kPrimary,
+  kExternal,
+  kVirtual,
+};
+
+enum class ExternalStatus : int {
+  kInvalid,
+  kOffline,
+  kOnline,
+  kPause,
+  kResume,
+};
+
+enum class DynRefreshRateOp : int {
+  kInvalid,
+  kDisableMetadata,
+  kEnableMetadata,
+  kSetBinder,
+};
+
+enum class DisplayPortType : int {
+  kInvalid,
+  kDefault,
+  kDsi,
+  kDtv,
+  kWriteback,
+  kLvds,
+  kEdp,
+  kDp,
+};
+
+enum class PowerMode : int {
+  kOff,
+  kDoze,
+  kOn,
+  kDozeSuspend,
+};
+
+enum class QsyncMode : int {
+  kNone,
+  kWaitForFencesOneFrame,
+  kWaitForFencesEachFrame,
+  kWaitForCommitEachFrame,
+};
+
+// Input and Output Params structures
+struct Attributes {
+  uint32_t vsync_period = 0;
+  uint32_t x_res = 0;
+  uint32_t y_res = 0;
+  float x_dpi = 0;
+  float y_dpi = 0;
+  DisplayPortType panel_type = DisplayPortType::kDefault;
+  bool is_yuv = 0;
+};
+
+struct HDRCapsParams {
+  std::vector<int> supported_hdr_types = {};
+  float max_luminance = 0;
+  float max_avg_luminance = 0;
+  float min_luminance = 0;
+};
+
+struct StatusParams {
+  DisplayType dpy = DisplayType::kInvalid;
+  ExternalStatus status = ExternalStatus::kInvalid;
+};
+
+struct DynRefreshRateParams {
+  DynRefreshRateOp op = DynRefreshRateOp::kInvalid;
+  uint32_t refresh_rate = 0;
+};
+
+struct ConfigParams {
+  DisplayType dpy = DisplayType::kInvalid;
+  uint32_t config = 0;
+};
+
+struct AttributesParams {
+  uint32_t config_index = 0;
+  DisplayType dpy = DisplayType::kInvalid;
+};
+
+struct MinHdcpEncLevelChangedParams {
+  DisplayType dpy = DisplayType::kInvalid;
+  uint32_t min_enc_level = 0;
+};
+
+struct PartialUpdateParams {
+  DisplayType dpy = DisplayType::kInvalid;
+  bool enable = 0;
+};
+
+struct AnimationParams {
+  uint64_t display_id = 0;
+  bool animating = 0;
+};
+
+struct IdlePcParams {
+  bool enable = 0;
+  bool synchronous = 0;
+};
+
+struct DppsAdRoiParams {
+  uint32_t display_id = 0;
+  uint32_t h_start = 0;
+  uint32_t h_end = 0;
+  uint32_t v_start = 0;
+  uint32_t v_end = 0;
+  uint32_t factor_in = 0;
+  uint32_t factor_out = 0;
+};
+
+struct PowerModeParams {
+  uint32_t disp_id = 0;
+  PowerMode power_mode = PowerMode::kOff;
+};
+
+struct LayerMaskParams {
+  uint32_t disp_id = 0;
+  uint64_t layer_id = 0;
+};
+
+struct PanelLumAttrParams {
+  uint32_t disp_id = 0;
+  float min_lum = 0;
+  float max_lum = 0;
+};
+
+struct Rect {
+  uint32_t left = 0;
+  uint32_t top = 0;
+  uint32_t right = 0;
+  uint32_t bottom = 0;
+};
+
+struct CwbBufferParams {
+  uint32_t disp_id = 0;
+  Rect rect;
+  bool post_processed = 0;
+};
+
+struct DsiClkParams {
+  uint32_t disp_id = 0;
+  uint64_t bit_clk = 0;
+};
+
+struct QsyncModeParams {
+  uint32_t disp_id = 0;
+  QsyncMode mode = QsyncMode::kNone;
+};
+
+struct SmartPanelCfgParams {
+  uint32_t disp_id = 0;
+  uint32_t config_id = 0;
+};
+
+struct VdsParams {
+  uint32_t width = 0;
+  uint32_t height = 0;
+  int format = 0;
+};
+
+struct RotatorFormatParams {
+  int hal_format = 0;
+  bool ubwc = 0;
+};
+
+struct QsyncCallbackParams {
+  bool qsync_enabled = 0;
+  int refresh_rate = 0;
+  int qsync_refresh_rate = 0;
+};
+
+/* Callback Interface */
+class ConfigCallback {
+ public:
+  virtual void NotifyCWBBufferDone(int error, const native_handle_t *buffer) { }
+  virtual void NotifyQsyncChange(bool qsync_enabled, int refresh_rate, int qsync_refresh_rate) { }
+
+ protected:
+  virtual ~ConfigCallback() { }
+};
+
+#define DEFAULT_RET { return -EINVAL; }
+
+/* Config Interface */
+class ConfigInterface {
+ public:
+  virtual int IsDisplayConnected(DisplayType dpy, bool *connected) DEFAULT_RET
+  virtual int SetDisplayStatus(DisplayType dpy, ExternalStatus status) DEFAULT_RET
+  virtual int ConfigureDynRefreshRate(DynRefreshRateOp op, uint32_t refresh_rate) DEFAULT_RET
+  virtual int GetConfigCount(DisplayType dpy, uint32_t *count) DEFAULT_RET
+  virtual int GetActiveConfig(DisplayType dpy, uint32_t *config) DEFAULT_RET
+  virtual int SetActiveConfig(DisplayType dpy, uint32_t config) DEFAULT_RET
+  virtual int GetDisplayAttributes(uint32_t config_index, DisplayType dpy,
+                                   Attributes *attributes) DEFAULT_RET
+  virtual int SetPanelBrightness(uint32_t level) DEFAULT_RET
+  virtual int GetPanelBrightness(uint32_t *level) DEFAULT_RET
+  virtual int MinHdcpEncryptionLevelChanged(DisplayType dpy, uint32_t min_enc_level) DEFAULT_RET
+  virtual int RefreshScreen() DEFAULT_RET
+  virtual int ControlPartialUpdate(DisplayType dpy, bool enable) DEFAULT_RET
+  virtual int ToggleScreenUpdate(bool on) DEFAULT_RET
+  virtual int SetIdleTimeout(uint32_t value) DEFAULT_RET
+  virtual int GetHDRCapabilities(DisplayType dpy, HDRCapsParams *caps) DEFAULT_RET
+  virtual int SetCameraLaunchStatus(uint32_t on) DEFAULT_RET
+  virtual int DisplayBWTransactionPending(bool *status) DEFAULT_RET
+  virtual int SetDisplayAnimating(uint64_t display_id, bool animating) DEFAULT_RET
+  virtual int ControlIdlePowerCollapse(bool enable, bool synchronous) DEFAULT_RET
+  virtual int GetWriteBackCapabilities(bool *is_wb_ubwc_supported) DEFAULT_RET
+  virtual int SetDisplayDppsAdROI(uint32_t display_id, uint32_t h_start, uint32_t h_end,
+                                  uint32_t v_start, uint32_t v_end, uint32_t factor_in,
+                                  uint32_t factor_out) DEFAULT_RET
+  virtual int UpdateVSyncSourceOnPowerModeOff() DEFAULT_RET
+  virtual int UpdateVSyncSourceOnPowerModeDoze() DEFAULT_RET
+  virtual int SetPowerMode(uint32_t disp_id, PowerMode power_mode) DEFAULT_RET
+  virtual int IsPowerModeOverrideSupported(uint32_t disp_id, bool *supported) DEFAULT_RET
+  virtual int IsHDRSupported(uint32_t disp_id, bool *supported) DEFAULT_RET
+  virtual int IsWCGSupported(uint32_t disp_id, bool *supported) DEFAULT_RET
+  virtual int SetLayerAsMask(uint32_t disp_id, uint64_t layer_id) DEFAULT_RET
+  virtual int GetDebugProperty(const std::string prop_name, std::string value) DEFAULT_RET
+  virtual int GetActiveBuiltinDisplayAttributes(Attributes *attr) DEFAULT_RET
+  virtual int SetPanelLuminanceAttributes(uint32_t disp_id, float min_lum,
+                                          float max_lum) DEFAULT_RET
+  virtual int IsBuiltInDisplay(uint32_t disp_id, bool *is_builtin) DEFAULT_RET
+  virtual int IsAsyncVDSCreationSupported(bool *supported) DEFAULT_RET
+  virtual int CreateVirtualDisplay(uint32_t width, uint32_t height, int format) DEFAULT_RET
+  virtual int GetSupportedDSIBitClks(uint32_t disp_id, std::vector<uint64_t> bit_clks) DEFAULT_RET
+  virtual int GetDSIClk(uint32_t disp_id, uint64_t *bit_clk) DEFAULT_RET
+  virtual int SetDSIClk(uint32_t disp_id, uint64_t bit_clk) DEFAULT_RET
+  virtual int SetCWBOutputBuffer(uint32_t disp_id, const Rect rect, bool post_processed,
+                                 const native_handle_t *buffer) DEFAULT_RET
+  virtual int SetQsyncMode(uint32_t disp_id, QsyncMode mode) DEFAULT_RET
+  virtual int IsSmartPanelConfig(uint32_t disp_id, uint32_t config_id, bool *is_smart) DEFAULT_RET
+  virtual int IsRotatorSupportedFormat(int hal_format, bool ubwc, bool *supported) DEFAULT_RET
+  virtual int ControlQsyncCallback(bool enable) DEFAULT_RET
+
+ protected:
+  virtual ~ConfigInterface() { }
+};
+
+}  // namespace DisplayConfig
+
+#endif  // __CONFIG_DEFS_H__
diff --git a/services/config/device_interface.h b/services/config/device_interface.h
new file mode 100644
index 0000000..7d85910
--- /dev/null
+++ b/services/config/device_interface.h
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2020 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:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DEVICE_INTERFACE_H__
+#define __DEVICE_INTERFACE_H__
+
+#include "config_defs.h"
+
+namespace DisplayConfig {
+
+class ClientContext {
+ public:
+  virtual int RegisterClientContext(std::shared_ptr<ConfigCallback> callback,
+                                    ConfigInterface **intf) { return -EINVAL; }
+  virtual void UnRegisterClientContext(ConfigInterface *intf) { }
+
+ protected:
+  virtual ~ClientContext() { }
+};
+
+class DeviceInterface {
+ public:
+  static int RegisterDevice(ClientContext *intf);
+
+ protected:
+  virtual ~DeviceInterface() { }
+};
+
+}  // namespace DisplayConfig
+
+#endif  // __DEVICE_INTERFACE_H__
diff --git a/services/config/src/Android.bp b/services/config/src/Android.bp
new file mode 100644
index 0000000..355849a
--- /dev/null
+++ b/services/config/src/Android.bp
@@ -0,0 +1,24 @@
+cc_library_shared {
+    name: "libdisplayconfig.qti",
+    vendor_available: true,
+    product_specific: true,
+    cflags: [
+        "-Wno-sign-conversion",
+        "-Wno-unused-parameter",
+        "-DLOG_TAG=\"libdisplayconfigqti\"",
+    ],
+    shared_libs: [
+        "libhidlbase",
+        "libutils",
+        "vendor.display.config@2.0"
+    ],
+    header_libs: ["libhardware_headers", "display_intf_headers"],
+    srcs: [
+        "client_interface.cpp",
+        "client_impl.cpp",
+        "device_impl.cpp",
+        "device_interface.cpp",
+    ],
+    export_header_lib_headers: ["display_intf_headers"],
+}
+
diff --git a/services/config/src/client_impl.cpp b/services/config/src/client_impl.cpp
new file mode 100644
index 0000000..b3dd3e8
--- /dev/null
+++ b/services/config/src/client_impl.cpp
@@ -0,0 +1,864 @@
+/*
+* Copyright (c) 2020 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:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <string>
+#include <vector>
+
+#include "client_impl.h"
+
+namespace DisplayConfig {
+
+int ClientImpl::Init(std::string client_name, ConfigCallback *callback) {
+  display_config_ = IDisplayConfig::getService();
+  // Unable to find Display Config 2.0 service. Fail Init.
+  if (!display_config_) {
+    return -1;
+  }
+  int32_t error = 0;
+  uint64_t handle = 0;
+  auto hidl_callback = [&error, &handle] (int32_t err, uint64_t client_handle) {
+    error = err;
+    handle = client_handle;
+  };
+  int pid = getpid();
+  display_config_->registerClient(client_name + std::to_string(pid), this, hidl_callback);
+  client_handle_ = handle;
+  callback_ = callback;
+
+  return 0;
+}
+
+int ClientImpl::IsDisplayConnected(DisplayType dpy, bool *connected) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&dpy), sizeof(DisplayType));
+  const bool *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kIsDisplayConnected, input_params, {}, hidl_cb);
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const bool*>(data);
+
+  if (!error) {
+    *connected = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::SetDisplayStatus(DisplayType dpy, ExternalStatus status) {
+  struct StatusParams input = {dpy, status};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct StatusParams));
+  int error = 0;
+
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetDisplayStatus, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::ConfigureDynRefreshRate(DynRefreshRateOp op, uint32_t refresh_rate) {
+  struct DynRefreshRateParams input = {op, refresh_rate};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input),
+                             sizeof(struct DynRefreshRateParams));
+  int error = 0;
+
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kConfigureDynRefreshRate, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::GetConfigCount(DisplayType dpy, uint32_t *count) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&dpy), sizeof(DisplayType));
+  const uint32_t *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kGetConfigCount, input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const uint32_t*>(data);
+  *count = *output;
+
+  return error;
+}
+
+int ClientImpl::GetActiveConfig(DisplayType dpy, uint32_t *config) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&dpy), sizeof(DisplayType));
+  const uint32_t *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kGetActiveConfig, input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const uint32_t*>(data);
+  *config = *output;
+
+  return error;
+}
+
+int ClientImpl::SetActiveConfig(DisplayType dpy, uint32_t config) {
+  struct ConfigParams input = {dpy, config};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct ConfigParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetActiveConfig, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::GetDisplayAttributes(uint32_t config_index, DisplayType dpy,
+                                     Attributes *attributes) {
+  struct AttributesParams input = {config_index, dpy};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct AttributesParams));
+  const struct Attributes *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kGetDisplayAttributes, input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const Attributes*>(data);
+  if (!error) {
+    *attributes = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::SetPanelBrightness(uint32_t level) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&level), sizeof(uint32_t));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetPanelBrightness, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::GetPanelBrightness(uint32_t *level) {
+  const uint32_t *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kGetPanelBrightness, {}, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const uint32_t*>(data);
+  if (!error) {
+    *level = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::MinHdcpEncryptionLevelChanged(DisplayType dpy, uint32_t min_enc_level) {
+  struct MinHdcpEncLevelChangedParams input = {dpy, min_enc_level};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input),
+                             sizeof(struct MinHdcpEncLevelChangedParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kMinHdcpEncryptionLevelChanged,
+                           input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::RefreshScreen() {
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kRefreshScreen, {}, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::ControlPartialUpdate(DisplayType dpy, bool enable) {
+  struct PartialUpdateParams input = {dpy, enable};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input),
+                             sizeof(struct PartialUpdateParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kControlPartialUpdate, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::ToggleScreenUpdate(bool on) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&on), sizeof(bool));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kToggleScreenUpdate, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::SetIdleTimeout(uint32_t value) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&value), sizeof(uint32_t));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetIdleTimeout, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::GetHDRCapabilities(DisplayType dpy, HDRCapsParams *caps) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&dpy), sizeof(DisplayType));
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kGetHdrCapabilities, input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+
+  if (!error) {
+    const int32_t *hdr_caps;
+    const float *lum;
+    size_t size = output_params.size();
+    size_t hdr_caps_size = size - 3 * sizeof(float);
+    hdr_caps_size /= sizeof(int32_t);
+    hdr_caps = reinterpret_cast<const int32_t*>(data);
+    for (size_t i = 0; i < hdr_caps_size; i++) {
+      caps->supported_hdr_types.push_back(*hdr_caps);
+      hdr_caps++;
+    }
+    lum = reinterpret_cast<const float *>(hdr_caps);
+    caps->max_luminance = lum[0];
+    caps->max_avg_luminance = lum[1];
+    caps->min_luminance = lum[2];
+  }
+
+  return error;
+}
+
+int ClientImpl::SetCameraLaunchStatus(uint32_t on) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&on), sizeof(uint32_t));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetCameraLaunchStatus, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::DisplayBWTransactionPending(bool *status) {
+  const bool *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kDisplayBwTransactionPending, {}, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const bool*>(data);
+  if (!error) {
+    *status = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::SetDisplayAnimating(uint64_t display_id, bool animating) {
+  struct AnimationParams input = {display_id, animating};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct AnimationParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetDisplayAnimating, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::ControlIdlePowerCollapse(bool enable, bool synchronous) {
+  struct IdlePcParams input = {enable, synchronous};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct IdlePcParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kControlIdlePowerCollapse, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::GetWriteBackCapabilities(bool *is_wb_ubwc_supported) {
+  const bool *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kGetWritebackCapabilities, {}, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const bool*>(data);
+  if (!error) {
+    *is_wb_ubwc_supported = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::SetDisplayDppsAdROI(uint32_t display_id, uint32_t h_start,
+                                    uint32_t h_end, uint32_t v_start, uint32_t v_end,
+                                    uint32_t factor_in, uint32_t factor_out) {
+  struct DppsAdRoiParams input = {display_id, h_start, h_end, v_start, v_end,
+                                     factor_in, factor_out};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct DppsAdRoiParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetDisplayDppsAdRoi, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::UpdateVSyncSourceOnPowerModeOff() {
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kUpdateVsyncSourceOnPowerModeOff, {}, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::UpdateVSyncSourceOnPowerModeDoze() {
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kUpdateVsyncSourceOnPowerModeDoze, {}, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::SetPowerMode(uint32_t disp_id, PowerMode power_mode) {
+  struct PowerModeParams input = {disp_id, power_mode};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct PowerModeParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetPowerMode, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::IsPowerModeOverrideSupported(uint32_t disp_id, bool *supported) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&disp_id), sizeof(uint32_t));
+  const bool *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kIsPowerModeOverrideSupported,
+                           input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const bool*>(data);
+
+  if (!error) {
+    *supported = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::IsHDRSupported(uint32_t disp_id, bool *supported) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&disp_id), sizeof(uint32_t));
+  const bool *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kIsHdrSupported, input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const bool*>(data);
+
+  if (!error) {
+    *supported = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::IsWCGSupported(uint32_t disp_id, bool *supported) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&disp_id), sizeof(int32_t));
+  const bool *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kIsWcgSupported, input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const bool*>(data);
+
+  if (!error) {
+    *supported = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::SetLayerAsMask(uint32_t disp_id, uint64_t layer_id) {
+  struct LayerMaskParams input = {disp_id, layer_id};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct LayerMaskParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetLayerAsMask, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::GetDebugProperty(const std::string prop_name, std::string value) {
+  ByteStream input_params;
+  uint8_t *data_input = reinterpret_cast<uint8_t*>(const_cast<char*>(prop_name.data()));
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(data_input),
+                             prop_name.size() * sizeof(char));
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kGetDebugProperty, input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  const char *name = reinterpret_cast<const char *>(data);
+  std::string output(name);
+  if (!error) {
+    value = output;
+  }
+
+  return error;
+}
+
+int ClientImpl::GetActiveBuiltinDisplayAttributes(Attributes *attr) {
+  const struct Attributes *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kGetActiveBuiltinDisplayAttributes, {}, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const Attributes*>(data);
+  if (!error) {
+    *attr = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::SetPanelLuminanceAttributes(uint32_t disp_id, float min_lum, float max_lum) {
+  struct PanelLumAttrParams input = {disp_id, min_lum, max_lum};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct PanelLumAttrParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetPanelLuminanceAttributes, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::IsBuiltInDisplay(uint32_t disp_id, bool *is_builtin) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&disp_id), sizeof(uint32_t));
+  const bool *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kIsBuiltinDisplay, input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const bool*>(data);
+
+  if (!error) {
+    *is_builtin = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::SetCWBOutputBuffer(uint32_t disp_id, const Rect rect, bool post_processed,
+                                   const native_handle_t *buffer) {
+  if (callback_ == nullptr) {
+    return -EINVAL;
+  }
+
+  struct CwbBufferParams input = {disp_id, rect, post_processed};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct CwbBufferParams));
+
+  hidl_handle handle = buffer;
+  std::vector<hidl_handle> handle_vector;
+  handle_vector.push_back(buffer);
+  HandleStream input_handles = handle_vector;
+
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetCwbOutputBuffer, input_params,
+                           input_handles, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::GetSupportedDSIBitClks(uint32_t disp_id, std::vector<uint64_t> bit_clks) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&disp_id), sizeof(uint32_t));
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kGetSupportedDsiBitclks, input_params, {}, hidl_cb);
+
+  if (!error) {
+    const uint8_t *data = output_params.data();
+    const uint64_t *bit_clks_data = reinterpret_cast<const uint64_t *>(data);
+    int num_bit_clks = static_cast<int>(output_params.size() / sizeof(uint64_t));
+    for (int i = 0; i < num_bit_clks; i++) {
+      bit_clks.push_back(bit_clks_data[i]);
+    }
+  }
+
+  return error;
+}
+
+int ClientImpl::GetDSIClk(uint32_t disp_id, uint64_t *bit_clk) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&disp_id), sizeof(uint32_t));
+  const uint64_t *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kGetDsiClk, input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const uint64_t*>(data);
+
+  if (!error) {
+    *bit_clk = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::SetDSIClk(uint32_t disp_id, uint64_t bit_clk) {
+  struct DsiClkParams input = {disp_id, bit_clk};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct DsiClkParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetDsiClk, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::SetQsyncMode(uint32_t disp_id, QsyncMode mode) {
+  struct QsyncModeParams input = {disp_id, mode};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct QsyncModeParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSetQsyncMode, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::IsSmartPanelConfig(uint32_t disp_id, uint32_t config_id, bool *is_smart) {
+  struct SmartPanelCfgParams input = {disp_id, config_id};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input),
+                             sizeof(struct SmartPanelCfgParams));
+  const bool *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kIsSmartPanelConfig, input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const bool*>(data);
+
+  if (!error) {
+    *is_smart = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::IsAsyncVDSCreationSupported(bool *supported) {
+  const bool *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kIsAsyncVdsSupported, {}, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const bool*>(data);
+
+  if (!error) {
+    *supported = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t format) {
+  struct VdsParams input = {width, height, format};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct VdsParams));
+  int error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kCreateVirtualDisplay, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+int ClientImpl::IsRotatorSupportedFormat(int hal_format, bool ubwc, bool *supported) {
+  struct RotatorFormatParams input = {hal_format, ubwc};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input),
+                             sizeof(struct RotatorFormatParams));
+  const bool *output;
+  ByteStream output_params;
+  int error = 0;
+  auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+    output_params = params;
+  };
+
+  display_config_->perform(client_handle_, kIsRotatorSupportedFormat, input_params, {}, hidl_cb);
+
+  const uint8_t *data = output_params.data();
+  output = reinterpret_cast<const bool*>(data);
+
+  if (!error) {
+    *supported = *output;
+  }
+
+  return error;
+}
+
+int ClientImpl::ControlQsyncCallback(bool enable) {
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&enable), sizeof(bool));
+  int32_t error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kControlQsyncCallback, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+void ClientImpl::ParseNotifyCWBBufferDone(const ByteStream &input_params,
+                                          const HandleStream &input_handles) {
+  const int *error;
+
+  if (input_params.size() == 0 || input_handles.size() == 0) {
+    return;
+  }
+
+  const uint8_t *data = input_params.data();
+  error = reinterpret_cast<const int*>(data);
+  hidl_handle buffer = input_handles[0];
+  callback_->NotifyCWBBufferDone(*error, buffer.getNativeHandle());
+}
+
+void ClientImpl::ParseNotifyQsyncChange(const ByteStream &input_params) {
+  const struct QsyncCallbackParams *qsync_data;
+
+  if (input_params.size() == 0) {
+    return;
+  }
+
+  const uint8_t *data = input_params.data();
+  qsync_data = reinterpret_cast<const QsyncCallbackParams*>(data);
+  callback_->NotifyQsyncChange(qsync_data->qsync_enabled, qsync_data->refresh_rate,
+                               qsync_data->qsync_refresh_rate);
+}
+
+Return<void> ClientImpl::perform(uint32_t op_code, const ByteStream &input_params,
+                                 const HandleStream &input_handles) {
+  switch (op_code) {
+    case kSetCwbOutputBuffer:
+      ParseNotifyCWBBufferDone(input_params, input_handles);
+      break;
+    case kControlQsyncCallback:
+      ParseNotifyQsyncChange(input_params);
+      break;
+    default:
+      break;
+  }
+
+  return Void();
+}
+
+}  // namespace DisplayConfig
diff --git a/services/config/src/client_impl.h b/services/config/src/client_impl.h
new file mode 100644
index 0000000..f90a4e0
--- /dev/null
+++ b/services/config/src/client_impl.h
@@ -0,0 +1,115 @@
+/*
+* Copyright (c) 2020 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:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __CLIENT_IMPL_H__
+#define __CLIENT_IMPL_H__
+
+#include <vendor/display/config/2.0/IDisplayConfig.h>
+#include <hidl/HidlSupport.h>
+#include <config/client_interface.h>
+#include <string>
+#include <vector>
+
+#include "opcode_types.h"
+
+namespace DisplayConfig {
+
+using vendor::display::config::V2_0::IDisplayConfig;
+using vendor::display::config::V2_0::IDisplayConfigCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_vec;
+
+typedef hidl_vec<uint8_t> ByteStream;
+typedef hidl_vec<hidl_handle> HandleStream;
+
+class ClientImpl : public ClientInterface, public IDisplayConfigCallback {
+ public:
+  int Init(std::string client_name, ConfigCallback *callback);
+
+  virtual int IsDisplayConnected(DisplayType dpy, bool *connected);
+  virtual int SetDisplayStatus(DisplayType dpy, ExternalStatus status);
+  virtual int ConfigureDynRefreshRate(DynRefreshRateOp op, uint32_t refresh_rate);
+  virtual int GetConfigCount(DisplayType dpy, uint32_t *count);
+  virtual int GetActiveConfig(DisplayType dpy, uint32_t *config);
+  virtual int SetActiveConfig(DisplayType dpy, uint32_t config);
+  virtual int GetDisplayAttributes(uint32_t config_index, DisplayType dpy, Attributes *attributes);
+  virtual int SetPanelBrightness(uint32_t level);
+  virtual int GetPanelBrightness(uint32_t *level);
+  virtual int MinHdcpEncryptionLevelChanged(DisplayType dpy, uint32_t min_enc_level);
+  virtual int RefreshScreen();
+  virtual int ControlPartialUpdate(DisplayType dpy, bool enable);
+  virtual int ToggleScreenUpdate(bool on);
+  virtual int SetIdleTimeout(uint32_t value);
+  virtual int GetHDRCapabilities(DisplayType dpy, HDRCapsParams *caps);
+  virtual int SetCameraLaunchStatus(uint32_t on);
+  virtual int DisplayBWTransactionPending(bool *status);
+  virtual int SetDisplayAnimating(uint64_t display_id, bool animating);
+  virtual int ControlIdlePowerCollapse(bool enable, bool synchronous);
+  virtual int GetWriteBackCapabilities(bool *is_wb_ubwc_supported);
+  virtual int SetDisplayDppsAdROI(uint32_t display_id, uint32_t h_start, uint32_t h_end,
+                                  uint32_t v_start, uint32_t v_end, uint32_t factor_in,
+                                  uint32_t factor_out);
+  virtual int UpdateVSyncSourceOnPowerModeOff();
+  virtual int UpdateVSyncSourceOnPowerModeDoze();
+  virtual int SetPowerMode(uint32_t disp_id, PowerMode power_mode);
+  virtual int IsPowerModeOverrideSupported(uint32_t disp_id, bool *supported);
+  virtual int IsHDRSupported(uint32_t disp_id, bool *supported);
+  virtual int IsWCGSupported(uint32_t disp_id, bool *supported);
+  virtual int SetLayerAsMask(uint32_t disp_id, uint64_t layer_id);
+  virtual int GetDebugProperty(const std::string prop_name, std::string value);
+  virtual int GetActiveBuiltinDisplayAttributes(Attributes *attr);
+  virtual int SetPanelLuminanceAttributes(uint32_t disp_id, float min_lum, float max_lum);
+  virtual int IsBuiltInDisplay(uint32_t disp_id, bool *is_builtin);
+  virtual int IsAsyncVDSCreationSupported(bool *supported);
+  virtual int CreateVirtualDisplay(uint32_t width, uint32_t height, int format);
+  virtual int GetSupportedDSIBitClks(uint32_t disp_id, std::vector<uint64_t> bit_clks);
+  virtual int GetDSIClk(uint32_t disp_id, uint64_t *bit_clk);
+  virtual int SetDSIClk(uint32_t disp_id, uint64_t bit_clk);
+  virtual int SetCWBOutputBuffer(uint32_t disp_id, const Rect rect, bool post_processed,
+                                 const native_handle_t *buffer);
+  virtual int SetQsyncMode(uint32_t disp_id, QsyncMode mode);
+  virtual int IsSmartPanelConfig(uint32_t disp_id, uint32_t config_id, bool *is_smart);
+  virtual int IsRotatorSupportedFormat(int hal_format, bool ubwc, bool *supported);
+  virtual int ControlQsyncCallback(bool enable);
+
+ private:
+  virtual Return<void> perform(uint32_t op_code, const ByteStream &input_params,
+                               const HandleStream &input_handles);
+  void ParseNotifyCWBBufferDone(const ByteStream &input_params, const HandleStream &input_handles);
+  void ParseNotifyQsyncChange(const ByteStream &input_params);
+  android::sp<IDisplayConfig> display_config_ = nullptr;
+  ConfigCallback *callback_ = nullptr;
+  uint64_t client_handle_ = 0;
+};
+
+}  // namespace DisplayConfig
+
+#endif  // __CLIENT_IMPL_H__
diff --git a/services/config/src/client_interface.cpp b/services/config/src/client_interface.cpp
new file mode 100644
index 0000000..94be1b9
--- /dev/null
+++ b/services/config/src/client_interface.cpp
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2020 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:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <string>
+
+#include "client_impl.h"
+
+namespace DisplayConfig {
+
+int ClientInterface::Create(std::string client_name, ConfigCallback *callback,
+                            ClientInterface **intf) {
+  if (!intf) {
+    return -1;
+  }
+
+  ClientImpl *impl = new ClientImpl();
+  if (!impl) {
+    return -1;
+  }
+
+  int ret = impl->Init(client_name, callback);
+  if (ret) {
+    delete impl;
+    return -1;
+  }
+
+  *intf = impl;
+  return 0;
+}
+
+void ClientInterface::Destroy(ClientInterface *intf) {
+  if (intf) {
+    delete static_cast<ClientImpl *>(intf);
+  }
+}
+
+}  // namespace DisplayConfig
diff --git a/services/config/src/device_impl.cpp b/services/config/src/device_impl.cpp
new file mode 100644
index 0000000..97e8a82
--- /dev/null
+++ b/services/config/src/device_impl.cpp
@@ -0,0 +1,835 @@
+/*
+* Copyright (c) 2020 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:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <string>
+#include <vector>
+
+#include "device_impl.h"
+
+namespace DisplayConfig {
+
+DeviceImpl *DeviceImpl::device_obj_ = nullptr;
+std::mutex DeviceImpl::device_lock_;
+
+int DeviceImpl::CreateInstance(ClientContext *intf) {
+  std::lock_guard<std::mutex> lock(device_lock_);
+  if (!device_obj_) {
+    device_obj_ = new DeviceImpl();
+    if (!device_obj_) {
+      return -1;
+    }
+
+    android::status_t status = device_obj_->IDisplayConfig::registerAsService();
+    // Unable to start Display Config 2.0 service. Fail Init.
+    if (status != android::OK) {
+      delete device_obj_;
+      device_obj_ = nullptr;
+      return -1;
+    }
+    device_obj_->intf_ = intf;
+  }
+
+  return 0;
+}
+
+Return<void> DeviceImpl::registerClient(const hidl_string &client_name,
+                                        const sp<IDisplayConfigCallback>& callback,
+                                        registerClient_cb _hidl_cb) {
+  int32_t error = 0;
+  std::string client_name_str = client_name.c_str();
+  if (client_name_str.empty()) {
+    error = -EINVAL;
+    _hidl_cb(error, 0);
+    return Void();
+  }
+
+  uint64_t client_handle = static_cast<uint64_t>(client_id_++);
+  std::shared_ptr<DeviceClientContext> device_client(new DeviceClientContext(callback));
+  if (callback) {
+    callback->linkToDeath(this, client_handle);
+  }
+  ConfigInterface *intf = nullptr;
+  intf_->RegisterClientContext(device_client, &intf);
+  device_client->SetDeviceConfigIntf(intf);
+
+  display_config_map_.emplace(std::make_pair(client_handle, device_client));
+  _hidl_cb(error, client_handle);
+  return Void();
+}
+
+void DeviceImpl::serviceDied(uint64_t client_handle,
+                             const android::wp<::android::hidl::base::V1_0::IBase>& callback) {
+  std::lock_guard<std::mutex> lock(death_service_mutex_);
+  auto itr = display_config_map_.find(client_handle);
+  std::shared_ptr<DeviceClientContext> client = itr->second;
+  ConfigInterface *intf = client->GetDeviceConfigIntf();
+  intf_->UnRegisterClientContext(intf);
+  client.reset();
+  display_config_map_.erase(itr);
+}
+
+DeviceImpl::DeviceClientContext::DeviceClientContext(const sp<IDisplayConfigCallback> callback) {
+  callback_ = callback;
+}
+
+void DeviceImpl::DeviceClientContext::SetDeviceConfigIntf(ConfigInterface *intf) {
+  intf_ = intf;
+}
+
+ConfigInterface* DeviceImpl::DeviceClientContext::GetDeviceConfigIntf() {
+  return intf_;
+}
+
+void DeviceImpl::DeviceClientContext::NotifyCWBBufferDone(int32_t error,
+                                                          const native_handle_t *buffer) {
+  ByteStream output_params;
+  HandleStream output_handles;
+  std::vector<hidl_handle> handles;
+
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&error), sizeof(int));
+  handles.push_back(buffer);
+  output_handles = handles;
+
+  auto status = callback_->perform(kSetCwbOutputBuffer, output_params, output_handles);
+  if (status.isDeadObject()) {
+    return;
+  }
+}
+
+void DeviceImpl::DeviceClientContext::NotifyQsyncChange(bool qsync_enabled, int32_t refresh_rate,
+                                                        int32_t qsync_refresh_rate) {
+  struct QsyncCallbackParams data = {qsync_enabled, refresh_rate, qsync_refresh_rate};
+  ByteStream output_params;
+
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&data), sizeof(data));
+
+  auto status = callback_->perform(kControlQsyncCallback, output_params, {});
+  if (status.isDeadObject()) {
+    return;
+  }
+}
+
+void DeviceImpl::DeviceClientContext::ParseIsDisplayConnected(const ByteStream &input_params,
+                                                              perform_cb _hidl_cb) {
+  const DisplayType *dpy;
+  bool connected = false;
+  ByteStream output_params;
+
+  const uint8_t *data = input_params.data();
+  dpy = reinterpret_cast<const DisplayType*>(data);
+  int32_t error = intf_->IsDisplayConnected(*dpy, &connected);
+
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&connected),
+                              sizeof(connected));
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetDisplayStatus(const ByteStream &input_params,
+                                                            perform_cb _hidl_cb) {
+  const struct StatusParams *display_status;
+  const uint8_t *data = input_params.data();
+  display_status = reinterpret_cast<const StatusParams*>(data);
+  int32_t error = intf_->SetDisplayStatus(display_status->dpy,
+                                          display_status->status);
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseConfigureDynRefreshRate(const ByteStream &input_params,
+                                                                   perform_cb _hidl_cb) {
+  const struct DynRefreshRateParams *dyn_refresh_data;
+  const uint8_t *data = input_params.data();
+  dyn_refresh_data = reinterpret_cast<const DynRefreshRateParams*>(data);
+  int32_t error = intf_->ConfigureDynRefreshRate(dyn_refresh_data->op,
+                                                 dyn_refresh_data->refresh_rate);
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetConfigCount(const ByteStream &input_params,
+                                                          perform_cb _hidl_cb) {
+  const DisplayType *dpy;
+  uint32_t count = 0;
+  ByteStream output_params;
+
+  if (input_params.size() == 0) {
+    _hidl_cb(-ENODATA, {}, {});
+    return;
+  }
+
+  const uint8_t *data = input_params.data();
+  dpy = reinterpret_cast<const DisplayType*>(data);
+  int32_t error = intf_->GetConfigCount(*dpy, &count);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&count),
+                              sizeof(uint32_t));
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetActiveConfig(const ByteStream &input_params,
+                                                           perform_cb _hidl_cb) {
+  const DisplayType *dpy;
+  uint32_t config = 0;
+  ByteStream output_params;
+
+  const uint8_t *data = input_params.data();
+  dpy = reinterpret_cast<const DisplayType*>(data);
+  int32_t error = intf_->GetActiveConfig(*dpy, &config);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&config),
+                              sizeof(uint32_t));
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetActiveConfig(const ByteStream &input_params,
+                                                           perform_cb _hidl_cb) {
+  const struct ConfigParams *set_active_cfg_data;
+
+  const uint8_t *data = input_params.data();
+  set_active_cfg_data = reinterpret_cast<const ConfigParams*>(data);
+  int32_t error = intf_->SetActiveConfig(set_active_cfg_data->dpy,
+                                         set_active_cfg_data->config);
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetDisplayAttributes(const ByteStream &input_params,
+                                                                perform_cb _hidl_cb) {
+  const struct AttributesParams *get_disp_attr_data;
+  struct Attributes attributes = {};
+  ByteStream output_params;
+  int32_t error = -EINVAL;
+
+  const uint8_t *data = input_params.data();
+  get_disp_attr_data = reinterpret_cast<const AttributesParams*>(data);
+  error = intf_->GetDisplayAttributes(get_disp_attr_data->config_index, get_disp_attr_data->dpy,
+                                      &attributes);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&attributes),
+                              sizeof(struct Attributes));
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetPanelBrightness(const ByteStream &input_params,
+                                                              perform_cb _hidl_cb) {
+  const uint32_t *level;
+  int32_t error = 0;
+
+  const uint8_t *data = input_params.data();
+  level = reinterpret_cast<const uint32_t*>(data);
+  error = intf_->SetPanelBrightness(*level);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetPanelBrightness(perform_cb _hidl_cb) {
+  uint32_t level = 0;
+  ByteStream output_params;
+  int32_t error = -EINVAL;
+
+  error = intf_->GetPanelBrightness(&level);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&level),
+                              sizeof(uint32_t));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseMinHdcpEncryptionLevelChanged(
+                                      const ByteStream &input_params,
+                                      perform_cb _hidl_cb) {
+  const struct MinHdcpEncLevelChangedParams *min_hdcp_enc_level_data;
+  int32_t error = 0;
+
+  const uint8_t *data = input_params.data();
+  min_hdcp_enc_level_data = reinterpret_cast<const MinHdcpEncLevelChangedParams*>(data);
+  error = intf_->MinHdcpEncryptionLevelChanged(min_hdcp_enc_level_data->dpy,
+                                               min_hdcp_enc_level_data->min_enc_level);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseRefreshScreen(perform_cb _hidl_cb) {
+  int32_t error = intf_->RefreshScreen();
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseControlPartialUpdate(const ByteStream &input_params,
+                                                                perform_cb _hidl_cb) {
+  const struct PartialUpdateParams *partial_update_data;
+  int32_t error = 0;
+
+  const uint8_t *data = input_params.data();
+  partial_update_data = reinterpret_cast<const PartialUpdateParams*>(data);
+  error = intf_->ControlPartialUpdate(partial_update_data->dpy, partial_update_data->enable);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseToggleScreenUpdate(const ByteStream &input_params,
+                                                              perform_cb _hidl_cb) {
+  const bool *on;
+  int32_t error = 0;
+
+  const uint8_t *data = input_params.data();
+  on = reinterpret_cast<const bool*>(data);
+  error = intf_->ToggleScreenUpdate(on);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetIdleTimeout(const ByteStream &input_params,
+                                                          perform_cb _hidl_cb) {
+  const uint32_t *timeout_value;
+
+  const uint8_t *data = input_params.data();
+  timeout_value = reinterpret_cast<const uint32_t*>(data);
+  int32_t error = intf_->SetIdleTimeout(*timeout_value);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetHdrCapabilities(const ByteStream &input_params,
+                                                              perform_cb _hidl_cb) {
+  const DisplayType *dpy;
+  ByteStream output_params;
+  struct HDRCapsParams hdr_caps;
+  int32_t *data_output;
+  int32_t error = -EINVAL;
+
+  const uint8_t *data = input_params.data();
+  dpy = reinterpret_cast<const DisplayType*>(data);
+  error = intf_->GetHDRCapabilities(*dpy, &hdr_caps);
+
+  data_output = reinterpret_cast<int32_t *>(malloc(sizeof(int32_t) *
+                hdr_caps.supported_hdr_types.size() + 3 * sizeof(float)));
+  for (int i = 0; i < hdr_caps.supported_hdr_types.size(); i++) {
+    data_output[i] = hdr_caps.supported_hdr_types[i];
+  }
+  float *lum = reinterpret_cast<float *>(&data_output[hdr_caps.supported_hdr_types.size()]);
+  *lum = hdr_caps.max_luminance;
+  lum++;
+  *lum = hdr_caps.max_avg_luminance;
+  lum++;
+  *lum = hdr_caps.min_luminance;
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(data_output), sizeof(int32_t) *
+                              hdr_caps.supported_hdr_types.size() + 3 * sizeof(float));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetCameraLaunchStatus(const ByteStream &input_params,
+                                                                 perform_cb _hidl_cb) {
+  const uint32_t *launch_status_data;
+
+  const uint8_t *data = input_params.data();
+  launch_status_data = reinterpret_cast<const uint32_t*>(data);
+
+  int32_t error = intf_->SetCameraLaunchStatus(*launch_status_data);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseDisplayBwTransactionPending(perform_cb _hidl_cb) {
+  bool status = true;
+  ByteStream output_params;
+
+  int32_t error = intf_->DisplayBWTransactionPending(&status);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&status),
+                              sizeof(bool));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetDisplayAnimating(const ByteStream &input_params,
+                                                               perform_cb _hidl_cb) {
+  const struct AnimationParams *display_animating_data;
+
+  const uint8_t *data = input_params.data();
+  display_animating_data = reinterpret_cast<const AnimationParams*>(data);
+  int32_t error = intf_->SetDisplayAnimating(display_animating_data->display_id,
+                                             display_animating_data->animating);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseControlIdlePowerCollapse(const ByteStream &input_params,
+                                                                    perform_cb _hidl_cb) {
+  const struct IdlePcParams *idle_pc_data;
+
+  const uint8_t *data = input_params.data();
+  idle_pc_data = reinterpret_cast<const IdlePcParams*>(data);
+  int32_t error = intf_->ControlIdlePowerCollapse(idle_pc_data->enable, idle_pc_data->synchronous);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetWritebackCapabilities(perform_cb _hidl_cb) {
+  bool is_wb_ubwc_supported;
+  ByteStream output_params;
+
+  int32_t error = intf_->GetWriteBackCapabilities(&is_wb_ubwc_supported);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&is_wb_ubwc_supported),
+                              sizeof(bool));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetDisplayDppsAdRoi(const ByteStream &input_params,
+                                                               perform_cb _hidl_cb) {
+  const struct DppsAdRoiParams *ad_roi_data;
+
+  const uint8_t *data = input_params.data();
+  ad_roi_data = reinterpret_cast<const DppsAdRoiParams*>(data);
+
+  int32_t error = intf_->SetDisplayDppsAdROI(ad_roi_data->display_id, ad_roi_data->h_start,
+                                             ad_roi_data->h_end, ad_roi_data->v_start,
+                                             ad_roi_data->v_end, ad_roi_data->factor_in,
+                                             ad_roi_data->factor_out);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseUpdateVsyncSourceOnPowerModeOff(perform_cb _hidl_cb) {
+  int32_t error = intf_->UpdateVSyncSourceOnPowerModeOff();
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseUpdateVsyncSourceOnPowerModeDoze(perform_cb _hidl_cb) {
+  int32_t error = intf_->UpdateVSyncSourceOnPowerModeDoze();
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetPowerMode(const ByteStream &input_params,
+                                                        perform_cb _hidl_cb) {
+  const struct PowerModeParams *set_power_mode_data;
+
+  const uint8_t *data = input_params.data();
+  set_power_mode_data = reinterpret_cast<const PowerModeParams*>(data);
+  int32_t error = intf_->SetPowerMode(set_power_mode_data->disp_id,
+                                      set_power_mode_data->power_mode);
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseIsPowerModeOverrideSupported(
+                                      const ByteStream &input_params,
+                                      perform_cb _hidl_cb) {
+  const uint32_t *disp_id;
+  bool supported = false;
+  ByteStream output_params;
+
+  const uint8_t *data = input_params.data();
+  disp_id = reinterpret_cast<const uint32_t*>(data);
+  int32_t error = intf_->IsPowerModeOverrideSupported(*disp_id, &supported);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&supported),
+                              sizeof(bool));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseIsHdrSupported(const ByteStream &input_params,
+                                                          perform_cb _hidl_cb) {
+  const uint32_t *disp_id;
+  bool supported;
+  ByteStream output_params;
+
+  const uint8_t *data = input_params.data();
+  disp_id = reinterpret_cast<const uint32_t*>(data);
+  int32_t error = intf_->IsHDRSupported(*disp_id, &supported);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&supported),
+                              sizeof(bool));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseIsWcgSupported(const ByteStream &input_params,
+                                                          perform_cb _hidl_cb) {
+  const int32_t *disp_id;
+  bool supported = false;
+  ByteStream output_params;
+
+  const uint8_t *data = input_params.data();
+  disp_id = reinterpret_cast<const int32_t*>(data);
+  int32_t error = intf_->IsWCGSupported(*disp_id, &supported);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&supported),
+                              sizeof(bool));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetLayerAsMask(const ByteStream &input_params,
+                                                          perform_cb _hidl_cb) {
+  const struct LayerMaskParams *layer_mask_data;
+
+  const uint8_t *data = input_params.data();
+  layer_mask_data = reinterpret_cast<const LayerMaskParams*>(data);
+  int32_t error = intf_->SetLayerAsMask(layer_mask_data->disp_id, layer_mask_data->layer_id);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetDebugProperty(const ByteStream &input_params,
+                                                            perform_cb _hidl_cb) {
+  std::string value;
+  ByteStream output_params;
+
+  const uint8_t *data = input_params.data();
+  const char *name = reinterpret_cast<const char *>(data);
+  std::string prop_name(name);
+  int32_t error = intf_->GetDebugProperty(prop_name, value);
+  uint8_t *data_output = reinterpret_cast<uint8_t*>(value.data());
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&data_output),
+                              value.size() * sizeof(char));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetActiveBuiltinDisplayAttributes(perform_cb _hidl_cb) {
+  struct Attributes attr;
+  ByteStream output_params;
+
+  int32_t error = intf_->GetActiveBuiltinDisplayAttributes(&attr);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&attr), sizeof(Attributes));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetPanelLuminanceAttributes(
+                                      const ByteStream &input_params,
+                                      perform_cb _hidl_cb) {
+  const struct PanelLumAttrParams *panel_lum_attr_data;
+
+  const uint8_t *data = input_params.data();
+  panel_lum_attr_data = reinterpret_cast<const PanelLumAttrParams*>(data);
+  int32_t error = intf_->SetPanelLuminanceAttributes(panel_lum_attr_data->disp_id,
+                                                     panel_lum_attr_data->min_lum,
+                                                     panel_lum_attr_data->max_lum);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseIsBuiltinDisplay(const ByteStream &input_params,
+                                                            perform_cb _hidl_cb) {
+  const uint32_t *disp_id;
+  bool is_builtin = false;
+  ByteStream output_params;
+
+  const uint8_t *data = input_params.data();
+  disp_id = reinterpret_cast<const uint32_t*>(data);
+  int32_t error = intf_->IsBuiltInDisplay(*disp_id, &is_builtin);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&is_builtin),
+                              sizeof(bool));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetCwbOutputBuffer(uint64_t clientHandle,
+                                                              const ByteStream &input_params,
+                                                              const HandleStream &input_handles,
+                                                              perform_cb _hidl_cb) {
+  const struct CwbBufferParams *cwb_buffer_data;
+
+  const uint8_t *data = input_params.data();
+  cwb_buffer_data = reinterpret_cast<const CwbBufferParams*>(data);
+  hidl_handle buffer = input_handles[0];
+
+  if (!callback_ || !buffer.getNativeHandle()) {
+    _hidl_cb(-1, {}, {});
+    return;
+  }
+
+  int32_t error = intf_->SetCWBOutputBuffer(cwb_buffer_data->disp_id , cwb_buffer_data->rect,
+                                            cwb_buffer_data->post_processed,
+                                            buffer.getNativeHandle());
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetSupportedDsiBitclks(const ByteStream &input_params,
+                                                                  perform_cb _hidl_cb) {
+  const uint32_t *disp_id;
+  ByteStream output_params;
+  std::vector<uint64_t> bit_clks;
+  uint64_t *bit_clks_data;
+
+  const uint8_t *data = input_params.data();
+  disp_id = reinterpret_cast<const uint32_t*>(data);
+  int32_t error = intf_->GetSupportedDSIBitClks(*disp_id, bit_clks);
+
+  bit_clks_data = reinterpret_cast<uint64_t *>(malloc(sizeof(uint64_t) * bit_clks.size()));
+  for (int i = 0; i < bit_clks.size(); i++) {
+    bit_clks_data[i] = bit_clks[i];
+  }
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(bit_clks_data),
+                              sizeof(uint64_t) * bit_clks.size());
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetDsiClk(const ByteStream &input_params,
+                                                     perform_cb _hidl_cb) {
+  const uint32_t *disp_id;
+  uint64_t bit_clk = 0;
+  ByteStream output_params;
+
+  const uint8_t *data = input_params.data();
+  disp_id = reinterpret_cast<const uint32_t*>(data);
+  int32_t error = intf_->GetDSIClk(*disp_id, &bit_clk);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&bit_clk),
+                              sizeof(uint64_t));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetDsiClk(const ByteStream &input_params,
+                                                     perform_cb _hidl_cb) {
+  const struct DsiClkParams *set_dsi_clk_data;
+
+  const uint8_t *data = input_params.data();
+  set_dsi_clk_data = reinterpret_cast<const DsiClkParams*>(data);
+  int32_t error = intf_->SetDSIClk(set_dsi_clk_data->disp_id, set_dsi_clk_data->bit_clk);
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSetQsyncMode(const ByteStream &input_params,
+                                                        perform_cb _hidl_cb) {
+  const struct QsyncModeParams *set_qsync_mode_data;
+
+  const uint8_t *data = input_params.data();
+  set_qsync_mode_data = reinterpret_cast<const QsyncModeParams*>(data);
+  int32_t error = intf_->SetQsyncMode(set_qsync_mode_data->disp_id, set_qsync_mode_data->mode);
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseIsSmartPanelConfig(const ByteStream &input_params,
+                                                              perform_cb _hidl_cb) {
+  const struct SmartPanelCfgParams *smart_panel_cfg_data;
+  bool is_smart = false;
+  ByteStream output_params;
+
+  const uint8_t *data = input_params.data();
+  smart_panel_cfg_data = reinterpret_cast<const SmartPanelCfgParams*>(data);
+  int32_t error = intf_->IsSmartPanelConfig(smart_panel_cfg_data->disp_id,
+                                            smart_panel_cfg_data->config_id, &is_smart);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&is_smart),
+                              sizeof(bool));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseIsAsyncVdsSupported(perform_cb _hidl_cb) {
+  bool is_supported;
+  ByteStream output_params;
+
+  int32_t error = intf_->IsAsyncVDSCreationSupported(&is_supported);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&is_supported),
+                             sizeof(bool));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseCreateVirtualDisplay(const ByteStream &input_params,
+                                                                perform_cb _hidl_cb) {
+  const struct VdsParams *vds_input_data;
+
+  const uint8_t *data = input_params.data();
+  vds_input_data = reinterpret_cast<const VdsParams*>(data);
+
+  int32_t error = intf_->CreateVirtualDisplay(vds_input_data->width, vds_input_data->height,
+                                              vds_input_data->format);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseIsRotatorSupportedFormat(const ByteStream &input_params,
+                                                                    perform_cb _hidl_cb) {
+  const struct RotatorFormatParams *input_data;
+  bool supported = false;
+  ByteStream output_params;
+
+  const uint8_t *data = input_params.data();
+  input_data = reinterpret_cast<const RotatorFormatParams*>(data);
+  int32_t error = intf_->IsRotatorSupportedFormat(input_data->hal_format, input_data->ubwc,
+                                                  &supported);
+  output_params.setToExternal(reinterpret_cast<uint8_t*>(&supported),
+                              sizeof(bool));
+
+  _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseControlQsyncCallback(uint64_t client_handle,
+                                                                const ByteStream &input_params,
+                                                                perform_cb _hidl_cb) {
+  const bool *enable;
+
+  const uint8_t *data = input_params.data();
+  enable = reinterpret_cast<const bool*>(data);
+
+  int32_t error = intf_->ControlQsyncCallback(*enable);
+
+  _hidl_cb(error, {}, {});
+}
+
+Return<void> DeviceImpl::perform(uint64_t client_handle, uint32_t op_code,
+                                 const ByteStream &input_params, const HandleStream &input_handles,
+                                 perform_cb _hidl_cb) {
+  int32_t error = 0;
+  auto itr = display_config_map_.find(client_handle);
+  if (itr == display_config_map_.end()) {
+    error = -EINVAL;
+    _hidl_cb(error, {}, {});
+    return Void();
+  }
+
+  std::shared_ptr<DeviceClientContext> client = itr->second;
+  switch (op_code) {
+    case kIsDisplayConnected:
+      client->ParseIsDisplayConnected(input_params, _hidl_cb);
+      break;
+    case kSetDisplayStatus:
+      client->ParseSetDisplayStatus(input_params, _hidl_cb);
+      break;
+    case kConfigureDynRefreshRate:
+      client->ParseConfigureDynRefreshRate(input_params, _hidl_cb);
+      break;
+    case kGetConfigCount:
+      client->ParseGetConfigCount(input_params, _hidl_cb);
+      break;
+    case kGetActiveConfig:
+      client->ParseGetActiveConfig(input_params, _hidl_cb);
+      break;
+    case kSetActiveConfig:
+      client->ParseSetActiveConfig(input_params, _hidl_cb);
+      break;
+    case kGetDisplayAttributes:
+      client->ParseGetDisplayAttributes(input_params, _hidl_cb);
+      break;
+    case kSetPanelBrightness:
+      client->ParseSetPanelBrightness(input_params, _hidl_cb);
+      break;
+    case kGetPanelBrightness:
+      client->ParseGetPanelBrightness(_hidl_cb);
+      break;
+    case kMinHdcpEncryptionLevelChanged:
+      client->ParseMinHdcpEncryptionLevelChanged(input_params, _hidl_cb);
+      break;
+    case kRefreshScreen:
+      client->ParseRefreshScreen(_hidl_cb);
+      break;
+    case kControlPartialUpdate:
+      client->ParseControlPartialUpdate(input_params, _hidl_cb);
+      break;
+    case kToggleScreenUpdate:
+      client->ParseToggleScreenUpdate(input_params, _hidl_cb);
+      break;
+    case kSetIdleTimeout:
+      client->ParseSetIdleTimeout(input_params, _hidl_cb);
+      break;
+    case kGetHdrCapabilities:
+      client->ParseGetHdrCapabilities(input_params, _hidl_cb);
+      break;
+    case kSetCameraLaunchStatus:
+      client->ParseSetCameraLaunchStatus(input_params, _hidl_cb);
+      break;
+    case kDisplayBwTransactionPending:
+      client->ParseDisplayBwTransactionPending(_hidl_cb);
+      break;
+    case kSetDisplayAnimating:
+      client->ParseSetDisplayAnimating(input_params, _hidl_cb);
+      break;
+    case kControlIdlePowerCollapse:
+      client->ParseControlIdlePowerCollapse(input_params, _hidl_cb);
+      break;
+    case kGetWritebackCapabilities:
+      client->ParseGetWritebackCapabilities(_hidl_cb);
+      break;
+    case kSetDisplayDppsAdRoi:
+      client->ParseSetDisplayDppsAdRoi(input_params, _hidl_cb);
+      break;
+    case kUpdateVsyncSourceOnPowerModeOff:
+      client->ParseUpdateVsyncSourceOnPowerModeOff(_hidl_cb);
+      break;
+    case kUpdateVsyncSourceOnPowerModeDoze:
+      client->ParseUpdateVsyncSourceOnPowerModeDoze(_hidl_cb);
+      break;
+    case kSetPowerMode:
+      client->ParseSetPowerMode(input_params, _hidl_cb);
+      break;
+    case kIsPowerModeOverrideSupported:
+      client->ParseIsPowerModeOverrideSupported(input_params, _hidl_cb);
+      break;
+    case kIsHdrSupported:
+      client->ParseIsHdrSupported(input_params, _hidl_cb);
+      break;
+    case kIsWcgSupported:
+      client->ParseIsWcgSupported(input_params, _hidl_cb);
+      break;
+    case kSetLayerAsMask:
+      client->ParseSetLayerAsMask(input_params, _hidl_cb);
+      break;
+    case kGetDebugProperty:
+      client->ParseGetDebugProperty(input_params, _hidl_cb);
+      break;
+    case kGetActiveBuiltinDisplayAttributes:
+      client->ParseGetActiveBuiltinDisplayAttributes(_hidl_cb);
+      break;
+    case kSetPanelLuminanceAttributes:
+      client->ParseSetPanelLuminanceAttributes(input_params, _hidl_cb);
+      break;
+    case kIsBuiltinDisplay:
+      client->ParseIsBuiltinDisplay(input_params, _hidl_cb);
+      break;
+    case kSetCwbOutputBuffer:
+      client->ParseSetCwbOutputBuffer(client_handle, input_params, input_handles, _hidl_cb);
+      break;
+    case kGetSupportedDsiBitclks:
+      client->ParseGetSupportedDsiBitclks(input_params, _hidl_cb);
+      break;
+    case kGetDsiClk:
+      client->ParseGetDsiClk(input_params, _hidl_cb);
+      break;
+    case kSetDsiClk:
+      client->ParseSetDsiClk(input_params, _hidl_cb);
+      break;
+    case kSetQsyncMode:
+      client->ParseSetQsyncMode(input_params, _hidl_cb);
+      break;
+    case kIsSmartPanelConfig:
+      client->ParseIsSmartPanelConfig(input_params, _hidl_cb);
+      break;
+    case kIsAsyncVdsSupported:
+      client->ParseIsAsyncVdsSupported(_hidl_cb);
+      break;
+    case kCreateVirtualDisplay:
+      client->ParseCreateVirtualDisplay(input_params, _hidl_cb);
+      break;
+    case kIsRotatorSupportedFormat:
+      client->ParseIsRotatorSupportedFormat(input_params, _hidl_cb);
+      break;
+    case kControlQsyncCallback:
+      client->ParseControlQsyncCallback(client_handle, input_params, _hidl_cb);
+      break;
+    default:
+      break;
+  }
+  return Void();
+}
+
+}  // namespace DisplayConfig
diff --git a/services/config/src/device_impl.h b/services/config/src/device_impl.h
new file mode 100644
index 0000000..96e9351
--- /dev/null
+++ b/services/config/src/device_impl.h
@@ -0,0 +1,141 @@
+/*
+* Copyright (c) 2020 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:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DEVICE_IMPL_H__
+#define __DEVICE_IMPL_H__
+
+#include <vendor/display/config/2.0/IDisplayConfig.h>
+#include <hidl/HidlSupport.h>
+
+#include <config/device_interface.h>
+#include <map>
+#include <utility>
+#include <string>
+#include <vector>
+
+#include "opcode_types.h"
+
+namespace DisplayConfig {
+
+using vendor::display::config::V2_0::IDisplayConfig;
+using vendor::display::config::V2_0::IDisplayConfigCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::sp;
+
+typedef hidl_vec<uint8_t> ByteStream;
+typedef hidl_vec<hidl_handle> HandleStream;
+
+class DeviceImpl : public IDisplayConfig, public android::hardware::hidl_death_recipient {
+ public:
+  static int CreateInstance(ClientContext *intf);
+
+ private:
+  class DeviceClientContext : public ConfigCallback {
+   public:
+    explicit DeviceClientContext(const sp<IDisplayConfigCallback> callback);
+
+    void SetDeviceConfigIntf(ConfigInterface *intf);
+    ConfigInterface* GetDeviceConfigIntf();
+
+    virtual void NotifyCWBBufferDone(int32_t error, const native_handle_t *buffer);
+    virtual void NotifyQsyncChange(bool qsync_enabled, int32_t refresh_rate,
+                                   int32_t qsync_refresh_rate);
+
+    void ParseIsDisplayConnected(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseSetDisplayStatus(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseConfigureDynRefreshRate(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseGetConfigCount(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseGetActiveConfig(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseSetActiveConfig(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseGetDisplayAttributes(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseSetPanelBrightness(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseGetPanelBrightness(perform_cb _hidl_cb);
+    void ParseMinHdcpEncryptionLevelChanged(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseRefreshScreen(perform_cb _hidl_cb);
+    void ParseControlPartialUpdate(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseToggleScreenUpdate(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseSetIdleTimeout(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseGetHdrCapabilities(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseSetCameraLaunchStatus(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseDisplayBwTransactionPending(perform_cb _hidl_cb);
+    void ParseSetDisplayAnimating(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseControlIdlePowerCollapse(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseGetWritebackCapabilities(perform_cb _hidl_cb);
+    void ParseSetDisplayDppsAdRoi(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseUpdateVsyncSourceOnPowerModeOff(perform_cb _hidl_cb);
+    void ParseUpdateVsyncSourceOnPowerModeDoze(perform_cb _hidl_cb);
+    void ParseSetPowerMode(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseIsPowerModeOverrideSupported(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseIsHdrSupported(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseIsWcgSupported(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseSetLayerAsMask(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseGetDebugProperty(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseGetActiveBuiltinDisplayAttributes(perform_cb _hidl_cb);
+    void ParseSetPanelLuminanceAttributes(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseIsBuiltinDisplay(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseSetCwbOutputBuffer(uint64_t clientHandle, const ByteStream &input_params,
+                                 const HandleStream &inputHandles, perform_cb _hidl_cb);
+    void ParseGetSupportedDsiBitclks(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseGetDsiClk(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseSetDsiClk(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseSetQsyncMode(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseIsSmartPanelConfig(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseIsAsyncVdsSupported(perform_cb _hidl_cb);
+    void ParseCreateVirtualDisplay(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseIsRotatorSupportedFormat(const ByteStream &input_params, perform_cb _hidl_cb);
+    void ParseControlQsyncCallback(uint64_t client_handle, const ByteStream &input_params,
+                                   perform_cb _hidl_cb);
+
+   private:
+    ConfigInterface *intf_ = nullptr;
+    sp<IDisplayConfigCallback> callback_;
+  };
+
+  Return<void> registerClient(const hidl_string &client_name, const sp<IDisplayConfigCallback>& cb,
+                              registerClient_cb _hidl_cb) override;
+  Return<void> perform(uint64_t client_handle, uint32_t op_code, const ByteStream &input_params,
+                       const HandleStream &input_handles, perform_cb _hidl_cb) override;
+  void serviceDied(uint64_t client_handle,
+                   const android::wp<::android::hidl::base::V1_0::IBase>& callback);
+
+  ClientContext *intf_ = nullptr;
+  std::map<uint64_t, std::shared_ptr<DeviceClientContext>> display_config_map_;
+  uint64_t client_id_ = 0;
+  std::mutex death_service_mutex_;
+  static DeviceImpl *device_obj_;
+  static std::mutex device_lock_;
+};
+
+}  // namespace DisplayConfig
+
+#endif  // __DEVICE_IMPL_H__
diff --git a/services/config/src/device_interface.cpp b/services/config/src/device_interface.cpp
new file mode 100644
index 0000000..0c2d6b7
--- /dev/null
+++ b/services/config/src/device_interface.cpp
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 2020 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:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "device_impl.h"
+
+namespace DisplayConfig {
+
+int DeviceInterface::RegisterDevice(ClientContext *intf) {
+  if (!intf) {
+    return -1;
+  }
+
+  return DeviceImpl::CreateInstance(intf);
+}
+
+}  // namespace DisplayConfig
diff --git a/services/config/src/opcode_types.h b/services/config/src/opcode_types.h
new file mode 100644
index 0000000..1b28105
--- /dev/null
+++ b/services/config/src/opcode_types.h
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2020 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:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __OPCODE_TYPES_H__
+#define __OPCODE_TYPES_H__
+
+namespace DisplayConfig {
+
+enum OpCode {
+  kIsDisplayConnected = 0,
+  kSetDisplayStatus = 1,
+  kConfigureDynRefreshRate = 2,
+  kGetConfigCount = 3,
+  kGetActiveConfig = 4,
+  kSetActiveConfig = 5,
+  kGetDisplayAttributes = 6,
+  kSetPanelBrightness = 7,
+  kGetPanelBrightness =  8,
+  kMinHdcpEncryptionLevelChanged = 9,
+  kRefreshScreen = 10,
+  kControlPartialUpdate = 11,
+  kToggleScreenUpdate = 12,
+  kSetIdleTimeout = 13,
+  kGetHdrCapabilities = 14,
+  kSetCameraLaunchStatus = 15,
+  kDisplayBwTransactionPending = 16,
+  kSetDisplayAnimating = 17,
+  kControlIdlePowerCollapse = 18,
+  kGetWritebackCapabilities = 19,
+  kSetDisplayDppsAdRoi = 20,
+  kUpdateVsyncSourceOnPowerModeOff = 21,
+  kUpdateVsyncSourceOnPowerModeDoze = 22,
+  kSetPowerMode = 23,
+  kIsPowerModeOverrideSupported = 24,
+  kIsHdrSupported = 25,
+  kIsWcgSupported = 26,
+  kSetLayerAsMask = 27,
+  kGetDebugProperty = 28,
+  kGetActiveBuiltinDisplayAttributes = 29,
+  kSetPanelLuminanceAttributes = 30,
+  kIsBuiltinDisplay = 31,
+  kSetCwbOutputBuffer = 32,
+  kGetSupportedDsiBitclks = 33,
+  kGetDsiClk = 34,
+  kSetDsiClk = 35,
+  kSetQsyncMode = 36,
+  kIsSmartPanelConfig = 37,
+  kIsAsyncVdsSupported = 38,
+  kCreateVirtualDisplay = 39,
+  kIsRotatorSupportedFormat = 40,
+  kControlQsyncCallback = 41,
+};
+
+}  // namespace DisplayConfig
+
+#endif  // __OPCODE_TYPES_H__