Merge 2debc6b63c462be4b02c584803f3b4538663d8a9 on remote branch
Change-Id: I0daf7a7cae48d2d7d565396dc9ee544a779c89a9
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..26ce4fe
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,14 @@
+---
+Language: Cpp
+BasedOnStyle: Google
+Standard : C++11
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortBlocksOnASingleLine: false
+ColumnLimit: 100
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+DerivePointerAlignment: false
+PointerAlignment: Right
+#ReflowComments: false
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ad71dd6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+CMakeLists.txt
+.idea/
+.editorconfig
+.clang-complete
diff --git a/config/display-product-commonsys.mk b/config/display-product-commonsys.mk
new file mode 100644
index 0000000..98b22c3
--- /dev/null
+++ b/config/display-product-commonsys.mk
@@ -0,0 +1,22 @@
+PRODUCT_PACKAGES += libdisplayconfig.system \
+ libqdMetaData.system \
+ libgralloc.system.qti \
+ libdrm \
+ libsmomo.qti \
+ liblayerext.qti \
+ libsmomoconfig.qti \
+ libcomposerextn.qti \
+ libdisplayconfig.system.qti
+
+SOONG_CONFIG_NAMESPACES += qtidisplaycommonsys
+SOONG_CONFIG_NAMESPACES += qtiunifeddraw
+# Soong Keys
+SOONG_CONFIG_qtidisplaycommonsys := displayconfig_enabled
+SOONG_CONFIG_qtiunifeddraw := qtiunifeddraw_enabled
+# Soong Values
+SOONG_CONFIG_qtidisplaycommonsys_displayconfig_enabled := false
+SOONG_CONFIG_qtiunifeddraw_qtiunifeddraw_enabled := true
+
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+ SOONG_CONFIG_qtidisplaycommonsys_displayconfig_enabled := true
+endif
diff --git a/gralloc/Android.bp b/gralloc/Android.bp
new file mode 100644
index 0000000..2c28cf6
--- /dev/null
+++ b/gralloc/Android.bp
@@ -0,0 +1,22 @@
+cc_library_shared {
+ name: "libgralloc.system.qti",
+ system_ext_specific: true,
+ cflags: [
+ "-Wno-sign-conversion",
+ "-DLOG_TAG=\"qtigralloc\"",
+ ],
+ shared_libs: [
+ "liblog",
+ "libcutils",
+ "libutils",
+ "libgralloctypes",
+ "libhidlbase",
+ "libhardware",
+ "android.hardware.graphics.mapper@4.0",
+ ],
+
+ srcs: ["QtiGralloc.cpp"],
+
+ header_libs: ["display_intf_headers"],
+}
+
diff --git a/gralloc/QtiGralloc.cpp b/gralloc/QtiGralloc.cpp
new file mode 100644
index 0000000..831163a
--- /dev/null
+++ b/gralloc/QtiGralloc.cpp
@@ -0,0 +1,484 @@
+/*
+ * 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 "QtiGralloc.h"
+
+#include <log/log.h>
+namespace qtigralloc {
+
+using android::hardware::graphics::mapper::V4_0::IMapper;
+
+static sp<IMapper> getInstance() {
+ static sp<IMapper> mapper = IMapper::getService();
+ return mapper;
+}
+
+Error decodeMetadataState(hidl_vec<uint8_t> &in, bool *out) {
+ if (!in.size() || !out) {
+ return Error::BAD_VALUE;
+ }
+ memcpy(out, in.data(), METADATA_SET_SIZE);
+ return Error::NONE;
+}
+
+Error encodeMetadataState(bool *in, hidl_vec<uint8_t> *out) {
+ if (!in || !out) {
+ return Error::BAD_VALUE;
+ }
+ out->resize(sizeof(bool) * METADATA_SET_SIZE);
+ memcpy(out->data(), in, sizeof(bool) * METADATA_SET_SIZE);
+ return Error::NONE;
+}
+
+Error decodeColorMetadata(hidl_vec<uint8_t> &in, ColorMetaData *out) {
+ if (!in.size() || !out) {
+ return Error::BAD_VALUE;
+ }
+ memcpy(out, in.data(), sizeof(ColorMetaData));
+ return Error::NONE;
+}
+
+Error encodeColorMetadata(ColorMetaData &in, hidl_vec<uint8_t> *out) {
+ if (!out) {
+ return Error::BAD_VALUE;
+ }
+ out->resize(sizeof(ColorMetaData));
+ memcpy(out->data(), &in, sizeof(ColorMetaData));
+ return Error::NONE;
+}
+
+// decode the raw graphics metadata from bytestream and store it in 'data' member of
+// GraphicsMetadata struct during mapper->set call, 'size' member is unused.
+Error decodeGraphicsMetadata(hidl_vec<uint8_t> &in, GraphicsMetadata *out) {
+ if (!in.size() || !out) {
+ return Error::BAD_VALUE;
+ }
+ memcpy(&(out->data), in.data(), GRAPHICS_METADATA_SIZE_IN_BYTES);
+ return Error::NONE;
+}
+
+// encode only 'data' member of GraphicsMetadata struct for retrieval of
+// graphics metadata during mapper->get call
+Error encodeGraphicsMetadata(GraphicsMetadata &in, hidl_vec<uint8_t> *out) {
+ if (!out) {
+ return Error::BAD_VALUE;
+ }
+ out->resize(GRAPHICS_METADATA_SIZE_IN_BYTES);
+ memcpy(out->data(), &(in.data), GRAPHICS_METADATA_SIZE_IN_BYTES);
+ return Error::NONE;
+}
+
+// decode the raw graphics metadata from bytestream before presenting it to caller
+Error decodeGraphicsMetadataRaw(hidl_vec<uint8_t> &in, void *out) {
+ if (!in.size() || !out) {
+ return Error::BAD_VALUE;
+ }
+ memcpy(out, in.data(), GRAPHICS_METADATA_SIZE_IN_BYTES);
+ return Error::NONE;
+}
+
+// encode the raw graphics metadata in bytestream before calling mapper->set
+Error encodeGraphicsMetadataRaw(void *in, hidl_vec<uint8_t> *out) {
+ if (!in || !out) {
+ return Error::BAD_VALUE;
+ }
+ out->resize(GRAPHICS_METADATA_SIZE_IN_BYTES);
+ memcpy(out->data(), in, GRAPHICS_METADATA_SIZE_IN_BYTES);
+ return Error::NONE;
+}
+
+Error decodeUBWCStats(hidl_vec<uint8_t> &in, UBWCStats *out) {
+ if (!in.size() || !out) {
+ return Error::BAD_VALUE;
+ }
+ memcpy(out, in.data(), UBWC_STATS_ARRAY_SIZE * sizeof(UBWCStats));
+ return Error::NONE;
+}
+
+Error encodeUBWCStats(UBWCStats *in, hidl_vec<uint8_t> *out) {
+ if (!in || !out) {
+ return Error::BAD_VALUE;
+ }
+ out->resize(UBWC_STATS_ARRAY_SIZE * sizeof(UBWCStats));
+ memcpy(out->data(), in, UBWC_STATS_ARRAY_SIZE * sizeof(UBWCStats));
+ return Error::NONE;
+}
+
+Error decodeCVPMetadata(hidl_vec<uint8_t> &in, CVPMetadata *out) {
+ if (!in.size() || !out) {
+ return Error::BAD_VALUE;
+ }
+ memcpy(out, in.data(), sizeof(CVPMetadata));
+ return Error::NONE;
+}
+
+Error encodeCVPMetadata(CVPMetadata &in, hidl_vec<uint8_t> *out) {
+ if (!out) {
+ return Error::BAD_VALUE;
+ }
+ out->resize(sizeof(CVPMetadata));
+ memcpy(out->data(), &in, sizeof(CVPMetadata));
+ return Error::NONE;
+}
+
+Error decodeVideoHistogramMetadata(hidl_vec<uint8_t> &in, VideoHistogramMetadata *out) {
+ if (!in.size() || !out) {
+ return Error::BAD_VALUE;
+ }
+ memcpy(out, in.data(), sizeof(VideoHistogramMetadata));
+ return Error::NONE;
+}
+
+Error encodeVideoHistogramMetadata(VideoHistogramMetadata &in, hidl_vec<uint8_t> *out) {
+ if (!out) {
+ return Error::BAD_VALUE;
+ }
+ out->resize(sizeof(VideoHistogramMetadata));
+ memcpy(out->data(), &in, sizeof(VideoHistogramMetadata));
+ return Error::NONE;
+}
+
+Error decodeVideoTimestampInfo(hidl_vec<uint8_t> &in, VideoTimestampInfo *out) {
+ if (!in.size() || !out) {
+ return Error::BAD_VALUE;
+ }
+ memcpy(out, in.data(), sizeof(VideoTimestampInfo));
+ return Error::NONE;
+}
+
+Error encodeVideoTimestampInfo(VideoTimestampInfo &in, hidl_vec<uint8_t> *out) {
+ if (!out) {
+ return Error::BAD_VALUE;
+ }
+ out->resize(sizeof(VideoTimestampInfo));
+ memcpy(out->data(), &in, sizeof(VideoTimestampInfo));
+ return Error::NONE;
+}
+
+Error decodeYUVPlaneInfoMetadata(hidl_vec<uint8_t> &in, qti_ycbcr *out) {
+ if (!in.size() || !out) {
+ return Error::BAD_VALUE;
+ }
+ qti_ycbcr *p = reinterpret_cast<qti_ycbcr *>(in.data());
+ memcpy(out, in.data(), (YCBCR_LAYOUT_ARRAY_SIZE * sizeof(qti_ycbcr)));
+ return Error::NONE;
+}
+
+Error encodeYUVPlaneInfoMetadata(qti_ycbcr *in, hidl_vec<uint8_t> *out) {
+ if (!out) {
+ return Error::BAD_VALUE;
+ }
+ out->resize(YCBCR_LAYOUT_ARRAY_SIZE * sizeof(qti_ycbcr));
+ memcpy(out->data(), in, YCBCR_LAYOUT_ARRAY_SIZE * sizeof(qti_ycbcr));
+ return Error::NONE;
+}
+
+MetadataType getMetadataType(uint32_t in) {
+ switch (in) {
+ case QTI_VT_TIMESTAMP:
+ return MetadataType_VTTimestamp;
+ case QTI_VIDEO_PERF_MODE:
+ return MetadataType_VideoPerfMode;
+ case QTI_LINEAR_FORMAT:
+ return MetadataType_LinearFormat;
+ case QTI_SINGLE_BUFFER_MODE:
+ return MetadataType_SingleBufferMode;
+ case QTI_PP_PARAM_INTERLACED:
+ return MetadataType_PPParamInterlaced;
+ case QTI_MAP_SECURE_BUFFER:
+ return MetadataType_MapSecureBuffer;
+ case QTI_COLOR_METADATA:
+ return MetadataType_ColorMetadata;
+ case QTI_GRAPHICS_METADATA:
+ return MetadataType_GraphicsMetadata;
+ case QTI_UBWC_CR_STATS_INFO:
+ return MetadataType_UBWCCRStatsInfo;
+ case QTI_REFRESH_RATE:
+ return MetadataType_RefreshRate;
+ case QTI_CVP_METADATA:
+ return MetadataType_CVPMetadata;
+ case QTI_VIDEO_HISTOGRAM_STATS:
+ return MetadataType_VideoHistogramStats;
+ case QTI_VIDEO_TS_INFO:
+ return MetadataType_VideoTimestampInfo;
+ case QTI_FD:
+ return MetadataType_FD;
+ case QTI_PRIVATE_FLAGS:
+ return MetadataType_PrivateFlags;
+ case QTI_ALIGNED_WIDTH_IN_PIXELS:
+ return MetadataType_AlignedWidthInPixels;
+ case QTI_ALIGNED_HEIGHT_IN_PIXELS:
+ return MetadataType_AlignedHeightInPixels;
+ case QTI_STANDARD_METADATA_STATUS:
+ return MetadataType_StandardMetadataStatus;
+ case QTI_VENDOR_METADATA_STATUS:
+ return MetadataType_VendorMetadataStatus;
+ case QTI_BUFFER_TYPE:
+ return MetadataType_BufferType;
+ case QTI_CUSTOM_DIMENSIONS_STRIDE:
+ return MetadataType_CustomDimensionsStride;
+ case QTI_CUSTOM_DIMENSIONS_HEIGHT:
+ return MetadataType_CustomDimensionsHeight;
+ case QTI_RGB_DATA_ADDRESS:
+ return MetadataType_RgbDataAddress;
+ case QTI_COLORSPACE:
+ return MetadataType_ColorSpace;
+ case QTI_YUV_PLANE_INFO:
+ return MetadataType_YuvPlaneInfo;
+ default:
+ return MetadataType_Invalid;
+ }
+}
+
+Error get(void *buffer, uint32_t type, void *param) {
+ hidl_vec<uint8_t> bytestream;
+ sp<IMapper> mapper = getInstance();
+
+ MetadataType metadata_type = getMetadataType(type);
+ if (metadata_type == MetadataType_Invalid) {
+ param = nullptr;
+ return Error::UNSUPPORTED;
+ }
+
+ auto err = Error::UNSUPPORTED;
+ mapper->get(buffer, metadata_type, [&](const auto &tmpError, const auto &tmpByteStream) {
+ err = tmpError;
+ bytestream = tmpByteStream;
+ });
+
+ if (err != Error::NONE) {
+ return err;
+ }
+
+ switch (type) {
+ case QTI_VT_TIMESTAMP:
+ err = static_cast<Error>(android::gralloc4::decodeUint64(
+ qtigralloc::MetadataType_VTTimestamp, bytestream, reinterpret_cast<uint64_t *>(param)));
+ break;
+ case QTI_VIDEO_PERF_MODE:
+ err = static_cast<Error>(android::gralloc4::decodeUint32(
+ qtigralloc::MetadataType_VideoPerfMode, bytestream, reinterpret_cast<uint32_t *>(param)));
+ break;
+ case QTI_LINEAR_FORMAT:
+ err = static_cast<Error>(android::gralloc4::decodeUint32(
+ qtigralloc::MetadataType_LinearFormat, bytestream, reinterpret_cast<uint32_t *>(param)));
+ break;
+ case QTI_SINGLE_BUFFER_MODE:
+ err = static_cast<Error>(
+ android::gralloc4::decodeUint32(qtigralloc::MetadataType_SingleBufferMode, bytestream,
+ reinterpret_cast<uint32_t *>(param)));
+ break;
+ case QTI_PP_PARAM_INTERLACED:
+ err = static_cast<Error>(
+ android::gralloc4::decodeInt32(qtigralloc::MetadataType_PPParamInterlaced, bytestream,
+ reinterpret_cast<int32_t *>(param)));
+ break;
+ case QTI_MAP_SECURE_BUFFER:
+ err = static_cast<Error>(
+ android::gralloc4::decodeInt32(qtigralloc::MetadataType_MapSecureBuffer, bytestream,
+ reinterpret_cast<int32_t *>(param)));
+ break;
+ case QTI_COLOR_METADATA:
+ err = decodeColorMetadata(bytestream, reinterpret_cast<ColorMetaData *>(param));
+ break;
+ case QTI_GRAPHICS_METADATA:
+ err = decodeGraphicsMetadataRaw(bytestream, param);
+ break;
+ case QTI_UBWC_CR_STATS_INFO:
+ err = decodeUBWCStats(bytestream, reinterpret_cast<UBWCStats *>(param));
+ break;
+ case QTI_REFRESH_RATE:
+ err = static_cast<Error>(android::gralloc4::decodeFloat(
+ qtigralloc::MetadataType_RefreshRate, bytestream, reinterpret_cast<float *>(param)));
+ break;
+ case QTI_CVP_METADATA:
+ err = decodeCVPMetadata(bytestream, reinterpret_cast<CVPMetadata *>(param));
+ break;
+ case QTI_VIDEO_HISTOGRAM_STATS:
+ err = decodeVideoHistogramMetadata(bytestream,
+ reinterpret_cast<VideoHistogramMetadata *>(param));
+ break;
+ case QTI_VIDEO_TS_INFO:
+ err = decodeVideoTimestampInfo(bytestream, reinterpret_cast<VideoTimestampInfo *>(param));
+ break;
+ case QTI_FD:
+ err = static_cast<Error>(android::gralloc4::decodeInt32(
+ qtigralloc::MetadataType_FD, bytestream, reinterpret_cast<int32_t *>(param)));
+ break;
+ case QTI_PRIVATE_FLAGS:
+ err = static_cast<Error>(android::gralloc4::decodeInt32(
+ qtigralloc::MetadataType_PrivateFlags, bytestream, reinterpret_cast<int32_t *>(param)));
+ break;
+ case QTI_ALIGNED_WIDTH_IN_PIXELS:
+ err = static_cast<Error>(
+ android::gralloc4::decodeUint32(qtigralloc::MetadataType_AlignedWidthInPixels, bytestream,
+ reinterpret_cast<uint32_t *>(param)));
+ break;
+ case QTI_ALIGNED_HEIGHT_IN_PIXELS:
+ err = static_cast<Error>(
+ android::gralloc4::decodeUint32(qtigralloc::MetadataType_AlignedHeightInPixels,
+ bytestream, reinterpret_cast<uint32_t *>(param)));
+ break;
+ case QTI_STANDARD_METADATA_STATUS:
+ case QTI_VENDOR_METADATA_STATUS:
+ err = decodeMetadataState(bytestream, reinterpret_cast<bool *>(param));
+ break;
+ case QTI_BUFFER_TYPE:
+ err = static_cast<Error>(android::gralloc4::decodeUint32(
+ qtigralloc::MetadataType_BufferType, bytestream, reinterpret_cast<uint32_t *>(param)));
+ break;
+ case QTI_CUSTOM_DIMENSIONS_STRIDE:
+ err = static_cast<Error>(
+ android::gralloc4::decodeUint32(qtigralloc::MetadataType_CustomDimensionsStride,
+ bytestream, reinterpret_cast<uint32_t *>(param)));
+ break;
+ case QTI_CUSTOM_DIMENSIONS_HEIGHT:
+ err = static_cast<Error>(
+ android::gralloc4::decodeUint32(qtigralloc::MetadataType_CustomDimensionsHeight,
+ bytestream, reinterpret_cast<uint32_t *>(param)));
+ break;
+ case QTI_RGB_DATA_ADDRESS:
+ err = static_cast<Error>(
+ android::gralloc4::decodeUint64(qtigralloc::MetadataType_RgbDataAddress, bytestream,
+ reinterpret_cast<uint64_t *>(param)));
+ break;
+ case QTI_COLORSPACE:
+ err = static_cast<Error>(android::gralloc4::decodeUint32(
+ qtigralloc::MetadataType_ColorSpace, bytestream, reinterpret_cast<uint32_t *>(param)));
+ break;
+ case QTI_YUV_PLANE_INFO:
+ err = decodeYUVPlaneInfoMetadata(bytestream, reinterpret_cast<qti_ycbcr *>(param));
+ break;
+ default:
+ param = nullptr;
+ return Error::UNSUPPORTED;
+ }
+
+ return err;
+}
+
+Error set(void *buffer, uint32_t type, void *param) {
+ hidl_vec<uint8_t> bytestream;
+ sp<IMapper> mapper = getInstance();
+
+ Error err = Error::UNSUPPORTED;
+ MetadataType metadata_type = getMetadataType(type);
+ if (metadata_type == MetadataType_Invalid) {
+ return err;
+ }
+
+ switch (type) {
+ case QTI_VT_TIMESTAMP:
+ err = static_cast<Error>(android::gralloc4::encodeUint64(
+ qtigralloc::MetadataType_VTTimestamp, *reinterpret_cast<uint64_t *>(param), &bytestream));
+ break;
+ case QTI_VIDEO_PERF_MODE:
+ err = static_cast<Error>(
+ android::gralloc4::encodeUint32(qtigralloc::MetadataType_VideoPerfMode,
+ *reinterpret_cast<uint32_t *>(param), &bytestream));
+ break;
+ case QTI_LINEAR_FORMAT:
+ err = static_cast<Error>(
+ android::gralloc4::encodeUint32(qtigralloc::MetadataType_LinearFormat,
+ *reinterpret_cast<uint32_t *>(param), &bytestream));
+ break;
+ case QTI_SINGLE_BUFFER_MODE:
+ err = static_cast<Error>(
+ android::gralloc4::encodeUint32(qtigralloc::MetadataType_SingleBufferMode,
+ *reinterpret_cast<uint32_t *>(param), &bytestream));
+ break;
+ case QTI_PP_PARAM_INTERLACED:
+ err = static_cast<Error>(
+ android::gralloc4::encodeInt32(qtigralloc::MetadataType_PPParamInterlaced,
+ *reinterpret_cast<int32_t *>(param), &bytestream));
+ break;
+ case QTI_MAP_SECURE_BUFFER:
+ err = static_cast<Error>(
+ android::gralloc4::encodeInt32(qtigralloc::MetadataType_MapSecureBuffer,
+ *reinterpret_cast<int32_t *>(param), &bytestream));
+ break;
+ case QTI_COLOR_METADATA:
+ err = encodeColorMetadata(*reinterpret_cast<ColorMetaData *>(param), &bytestream);
+ break;
+ case QTI_GRAPHICS_METADATA:
+ err = encodeGraphicsMetadataRaw(param, &bytestream);
+ break;
+ case QTI_UBWC_CR_STATS_INFO:
+ err = encodeUBWCStats(reinterpret_cast<UBWCStats *>(param), &bytestream);
+ break;
+ case QTI_REFRESH_RATE:
+ err = static_cast<Error>(android::gralloc4::encodeFloat(
+ qtigralloc::MetadataType_RefreshRate, *reinterpret_cast<float *>(param), &bytestream));
+ break;
+ case QTI_CVP_METADATA:
+ err = encodeCVPMetadata(*reinterpret_cast<CVPMetadata *>(param), &bytestream);
+ break;
+ case QTI_VIDEO_HISTOGRAM_STATS:
+ err = encodeVideoHistogramMetadata(*reinterpret_cast<VideoHistogramMetadata *>(param),
+ &bytestream);
+ break;
+ case QTI_VIDEO_TS_INFO:
+ err = encodeVideoTimestampInfo(*reinterpret_cast<VideoTimestampInfo *>(param), &bytestream);
+ break;
+ default:
+ param = nullptr;
+ return Error::UNSUPPORTED;
+ }
+
+ if (err != Error::NONE) {
+ return err;
+ }
+
+ return mapper->set(reinterpret_cast<void *>(buffer), metadata_type, bytestream);
+}
+
+int getMetadataState(void *buffer, uint32_t type) {
+ bool metadata_set[METADATA_SET_SIZE];
+ Error err;
+ if (IS_VENDOR_METADATA_TYPE(type)) {
+ err = get(buffer, QTI_VENDOR_METADATA_STATUS, &metadata_set);
+ } else {
+ err = get(buffer, QTI_STANDARD_METADATA_STATUS, &metadata_set);
+ }
+
+ if (err != Error::NONE) {
+ ALOGE("Unable to get metadata state");
+ return -1;
+ }
+
+ if (IS_VENDOR_METADATA_TYPE(type)) {
+ return metadata_set[GET_VENDOR_METADATA_STATUS_INDEX(type)];
+ } else if (GET_STANDARD_METADATA_STATUS_INDEX(type) < METADATA_SET_SIZE) {
+ return metadata_set[GET_STANDARD_METADATA_STATUS_INDEX(type)];
+ } else {
+ return -1;
+ }
+}
+
+} // namespace qtigralloc
diff --git a/libqdmetadata/Android.bp b/libqdmetadata/Android.bp
new file mode 100644
index 0000000..181eb16
--- /dev/null
+++ b/libqdmetadata/Android.bp
@@ -0,0 +1,21 @@
+cc_library_shared {
+ name: "libqdMetaData.system",
+ system_ext_specific: true,
+ cflags: [
+ "-Wno-sign-conversion",
+ "-DLOG_TAG=\"qdmetadata\"",
+ "-D__QTI_DISPLAY_GRALLOC__",
+ ],
+ shared_libs: [
+ "liblog",
+ "libcutils",
+ "libutils",
+ "libhidlbase",
+ "libgralloc.system.qti",
+ "libgralloctypes",
+ ],
+ header_libs: ["libhardware_headers", "display_intf_headers"],
+ srcs: ["qdMetaData.cpp", "qd_utils.cpp"],
+ export_header_lib_headers: ["display_intf_headers"],
+}
+
diff --git a/libqdmetadata/Makefile.am b/libqdmetadata/Makefile.am
new file mode 100644
index 0000000..1fa7e64
--- /dev/null
+++ b/libqdmetadata/Makefile.am
@@ -0,0 +1,16 @@
+h_sources = qdMetaData.h
+
+cpp_sources = qdMetaData.cpp
+
+AM_CPPFLAGS += -D__QTI_NO_GRALLOC4__
+
+qdMetaData_includedir = $(pkgincludedir)/display
+qdMetaData_include_HEADERS = $(h_sources)
+
+lib_LTLIBRARIES = libqdMetaData.la
+libqdMetaData_la_CC = @CC@
+libqdMetaData_la_SOURCES = $(cpp_sources)
+libqdMetaData_la_CFLAGS = $(AM_CFLAGS) -DLOG_TAG=\"DisplayMetaData\"
+libqdMetaData_la_CPPFLAGS = $(AM_CPPFLAGS)
+libqdMetaData_LDADD = -lcutils -llog
+libqdMetaData_la_LDFLAGS = -shared -avoid-version
\ No newline at end of file
diff --git a/libqdmetadata/qdMetaData.cpp b/libqdmetadata/qdMetaData.cpp
new file mode 100644
index 0000000..228a634
--- /dev/null
+++ b/libqdmetadata/qdMetaData.cpp
@@ -0,0 +1,642 @@
+/*
+ * Copyright (c) 2012-2021, 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 "qdMetaData.h"
+
+#include <QtiGrallocPriv.h>
+#include <errno.h>
+#include <gralloc_priv.h>
+#ifndef __QTI_NO_GRALLOC4__
+#include <gralloctypes/Gralloc4.h>
+#endif
+#include <log/log.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include <cinttypes>
+
+static int colorMetaDataToColorSpace(ColorMetaData in, ColorSpace_t *out) {
+ if (in.colorPrimaries == ColorPrimaries_BT601_6_525 ||
+ in.colorPrimaries == ColorPrimaries_BT601_6_625) {
+ if (in.range == Range_Full) {
+ *out = ITU_R_601_FR;
+ } else {
+ *out = ITU_R_601;
+ }
+ } else if (in.colorPrimaries == ColorPrimaries_BT2020) {
+ if (in.range == Range_Full) {
+ *out = ITU_R_2020_FR;
+ } else {
+ *out = ITU_R_2020;
+ }
+ } else if (in.colorPrimaries == ColorPrimaries_BT709_5) {
+ if (in.range == Range_Full) {
+ *out = ITU_R_709_FR;
+ } else {
+ *out = ITU_R_709;
+ }
+ } else {
+ ALOGE(
+ "Cannot convert ColorMetaData to ColorSpace_t. "
+ "Primaries = %d, Range = %d",
+ in.colorPrimaries, in.range);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int colorSpaceToColorMetadata(ColorSpace_t in, ColorMetaData *out) {
+ out->transfer = Transfer_sRGB;
+ switch (in) {
+ case ITU_R_601:
+ out->colorPrimaries = ColorPrimaries_BT601_6_525;
+ out->range = Range_Limited;
+ break;
+ case ITU_R_601_FR:
+ out->colorPrimaries = ColorPrimaries_BT601_6_525;
+ out->range = Range_Full;
+ break;
+ case ITU_R_709:
+ out->colorPrimaries = ColorPrimaries_BT709_5;
+ out->range = Range_Limited;
+ break;
+ case ITU_R_709_FR:
+ out->colorPrimaries = ColorPrimaries_BT709_5;
+ out->range = Range_Full;
+ break;
+ case ITU_R_2020:
+ out->colorPrimaries = ColorPrimaries_BT2020;
+ out->range = Range_Limited;
+ break;
+ case ITU_R_2020_FR:
+ out->colorPrimaries = ColorPrimaries_BT2020;
+ out->range = Range_Full;
+ break;
+ default:
+ ALOGE("Cannot convert ColorSpace_t %d to ColorMetaData", in);
+ return -1;
+ break;
+ }
+
+ return 0;
+}
+
+#ifndef __QTI_NO_GRALLOC4__
+static bool getGralloc4Array(MetaData_t *metadata, int32_t paramType) {
+ switch (paramType) {
+ case SET_VT_TIMESTAMP:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VT_TIMESTAMP)];
+ case COLOR_METADATA:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_COLOR_METADATA)];
+ case PP_PARAM_INTERLACED:
+ return metadata
+ ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_PP_PARAM_INTERLACED)];
+ case SET_VIDEO_PERF_MODE:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_PERF_MODE)];
+ case SET_GRAPHICS_METADATA:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_GRAPHICS_METADATA)];
+ case SET_UBWC_CR_STATS_INFO:
+ return metadata
+ ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_UBWC_CR_STATS_INFO)];
+ case UPDATE_BUFFER_GEOMETRY:
+ return metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(
+ ::android::gralloc4::MetadataType_Crop.value)];
+ case UPDATE_REFRESH_RATE:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_REFRESH_RATE)];
+ case UPDATE_COLOR_SPACE:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_COLOR_METADATA)];
+ case MAP_SECURE_BUFFER:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_MAP_SECURE_BUFFER)];
+ case LINEAR_FORMAT:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_LINEAR_FORMAT)];
+ case SET_SINGLE_BUFFER_MODE:
+ return metadata
+ ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_SINGLE_BUFFER_MODE)];
+ case SET_CVP_METADATA:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_CVP_METADATA)];
+ case SET_VIDEO_HISTOGRAM_STATS:
+ return metadata
+ ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_HISTOGRAM_STATS)];
+ case SET_VIDEO_TS_INFO:
+ return metadata
+ ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_TS_INFO)];
+ case GET_S3D_FORMAT:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_S3D_FORMAT)];
+ default:
+ ALOGE("paramType %d not supported", paramType);
+ return false;
+ }
+}
+
+static void setGralloc4Array(MetaData_t *metadata, int32_t paramType, bool isSet) {
+ switch (paramType) {
+ case SET_VT_TIMESTAMP:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VT_TIMESTAMP)] = isSet;
+ break;
+ case COLOR_METADATA:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_COLOR_METADATA)] = isSet;
+ break;
+ case PP_PARAM_INTERLACED:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_PP_PARAM_INTERLACED)] =
+ isSet;
+ break;
+ case SET_VIDEO_PERF_MODE:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_PERF_MODE)] = isSet;
+ break;
+ case SET_GRAPHICS_METADATA:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_GRAPHICS_METADATA)] =
+ isSet;
+ break;
+ case SET_UBWC_CR_STATS_INFO:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_UBWC_CR_STATS_INFO)] =
+ isSet;
+ break;
+ case UPDATE_BUFFER_GEOMETRY:
+ metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(
+ ::android::gralloc4::MetadataType_Crop.value)] = isSet;
+ break;
+ case UPDATE_REFRESH_RATE:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_REFRESH_RATE)] = isSet;
+ break;
+ case UPDATE_COLOR_SPACE:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_COLOR_METADATA)] = isSet;
+ break;
+ case MAP_SECURE_BUFFER:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_MAP_SECURE_BUFFER)] =
+ isSet;
+ break;
+ case LINEAR_FORMAT:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_LINEAR_FORMAT)] = isSet;
+ break;
+ case SET_SINGLE_BUFFER_MODE:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_SINGLE_BUFFER_MODE)] =
+ isSet;
+ break;
+ case SET_CVP_METADATA:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_CVP_METADATA)] = isSet;
+ break;
+ case SET_VIDEO_HISTOGRAM_STATS:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_HISTOGRAM_STATS)] =
+ isSet;
+ break;
+ case SET_VIDEO_TS_INFO:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_TS_INFO)] =
+ isSet;
+ break;
+ case S3D_FORMAT:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_S3D_FORMAT)] = isSet;
+ break;
+ default:
+ ALOGE("paramType %d not supported in Gralloc4", paramType);
+ }
+}
+#else
+static bool getGralloc4Array(MetaData_t *metadata, int32_t paramType) {
+ return true;
+}
+
+static void setGralloc4Array(MetaData_t *metadata, int32_t paramType, bool isSet) {
+}
+#endif
+
+
+unsigned long getMetaDataSize() {
+ return static_cast<unsigned long>(ROUND_UP_PAGESIZE(sizeof(MetaData_t)));
+}
+
+// Cannot add default argument to existing function
+unsigned long getMetaDataSizeWithReservedRegion(uint64_t reserved_size) {
+ return static_cast<unsigned long>(ROUND_UP_PAGESIZE(sizeof(MetaData_t) + reserved_size));
+}
+
+static int validateAndMap(private_handle_t* handle) {
+ if (private_handle_t::validate(handle)) {
+ ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
+ return -1;
+ }
+ if (handle->fd_metadata < 0) {
+ // Metadata cannot be used
+ return -1;
+ }
+
+ if (!handle->base_metadata) {
+ auto size = getMetaDataSize();
+ void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
+ handle->fd_metadata, 0);
+ if (base == reinterpret_cast<void*>(MAP_FAILED)) {
+ ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s",
+ __func__, handle, handle->fd_metadata, strerror(errno));
+ return -1;
+ }
+ handle->base_metadata = (uintptr_t) base;
+ auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+ if (metadata->reservedSize) {
+ auto reserved_size = metadata->reservedSize;
+ munmap(reinterpret_cast<void *>(handle->base_metadata), getMetaDataSize());
+ handle->base_metadata = 0;
+ size = getMetaDataSizeWithReservedRegion(reserved_size);
+ void *new_base =
+ mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd_metadata, 0);
+ if (new_base == reinterpret_cast<void *>(MAP_FAILED)) {
+ ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s", __func__, handle,
+ handle->fd_metadata, strerror(errno));
+ return -1;
+ }
+ handle->base_metadata = (uintptr_t)new_base;
+ }
+ }
+ return 0;
+}
+
+static void unmapAndReset(private_handle_t *handle) {
+ if (private_handle_t::validate(handle) == 0 && handle->base_metadata) {
+ // If reservedSize is 0, the return value will be the same as getMetaDataSize
+ auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+ auto size = getMetaDataSizeWithReservedRegion(metadata->reservedSize);
+ munmap(reinterpret_cast<void *>(handle->base_metadata), size);
+ handle->base_metadata = 0;
+ }
+}
+
+int setMetaData(private_handle_t *handle, DispParamType paramType,
+ void *param) {
+ auto err = validateAndMap(handle);
+ if (err != 0)
+ return err;
+ return setMetaDataVa(reinterpret_cast<MetaData_t*>(handle->base_metadata),
+ paramType, param);
+}
+
+int setMetaDataVa(MetaData_t *data, DispParamType paramType,
+ void *param) {
+ if (data == nullptr)
+ return -EINVAL;
+ // If parameter is NULL reset the specific MetaData Key
+ if (!param) {
+ setGralloc4Array(data, paramType, false);
+ switch (paramType) {
+ case SET_VIDEO_PERF_MODE:
+ data->isVideoPerfMode = 0;
+ break;
+ case SET_CVP_METADATA:
+ data->cvpMetadata.size = 0;
+ break;
+ case SET_VIDEO_HISTOGRAM_STATS:
+ data->video_histogram_stats.stat_len = 0;
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ break;
+ }
+ // param unset
+ return 0;
+ }
+
+ setGralloc4Array(data, paramType, true);
+ switch (paramType) {
+ case PP_PARAM_INTERLACED:
+ data->interlaced = *((int32_t *)param);
+ break;
+ case UPDATE_BUFFER_GEOMETRY: {
+ BufferDim_t in = *((BufferDim_t *)param);
+ data->crop = {0, 0, in.sliceWidth, in.sliceHeight};
+ break;
+ }
+ case UPDATE_REFRESH_RATE:
+ data->refreshrate = *((float *)param);
+ break;
+ case UPDATE_COLOR_SPACE: {
+ ColorMetaData color = {};
+ if (!colorSpaceToColorMetadata(*((ColorSpace_t *)param), &color)) {
+ data->color = color;
+ break;
+ }
+ return -EINVAL;
+ }
+ case MAP_SECURE_BUFFER:
+ data->mapSecureBuffer = *((int32_t *)param);
+ break;
+ case S3D_FORMAT:
+ data->s3dFormat = *((uint32_t *)param);
+ break;
+ case LINEAR_FORMAT:
+ data->linearFormat = *((uint32_t *)param);
+ break;
+ case SET_SINGLE_BUFFER_MODE:
+ data->isSingleBufferMode = *((uint32_t *)param);
+ break;
+ case SET_VT_TIMESTAMP:
+ data->vtTimeStamp = *((uint64_t *)param);
+ break;
+ case COLOR_METADATA:
+ data->color = *((ColorMetaData *)param);
+ break;
+ case SET_UBWC_CR_STATS_INFO: {
+ struct UBWCStats *stats = (struct UBWCStats *)param;
+ int numelems = sizeof(data->ubwcCRStats) / sizeof(struct UBWCStats);
+ for (int i = 0; i < numelems; i++) {
+ data->ubwcCRStats[i] = stats[i];
+ }
+ break;
+ }
+ case SET_VIDEO_PERF_MODE:
+ data->isVideoPerfMode = *((uint32_t *)param);
+ break;
+ case SET_GRAPHICS_METADATA: {
+ GraphicsMetadata payload = *((GraphicsMetadata*)(param));
+ data->graphics_metadata.size = payload.size;
+ memcpy(data->graphics_metadata.data, payload.data,
+ sizeof(data->graphics_metadata.data));
+ break;
+ }
+ case SET_CVP_METADATA: {
+ struct CVPMetadata *cvpMetadata = (struct CVPMetadata *)param;
+ if (cvpMetadata->size <= CVP_METADATA_SIZE) {
+ data->cvpMetadata.size = cvpMetadata->size;
+ memcpy(data->cvpMetadata.payload, cvpMetadata->payload,
+ cvpMetadata->size);
+ data->cvpMetadata.capture_frame_rate = cvpMetadata->capture_frame_rate;
+ data->cvpMetadata.cvp_frame_rate = cvpMetadata->cvp_frame_rate;
+ data->cvpMetadata.flags = cvpMetadata->flags;
+ memcpy(data->cvpMetadata.reserved, cvpMetadata->reserved,
+ (8 * sizeof(uint32_t)));
+ } else {
+ setGralloc4Array(data, paramType, false);
+ ALOGE("%s: cvp metadata length %d is more than max size %d", __func__,
+ cvpMetadata->size, CVP_METADATA_SIZE);
+ return -EINVAL;
+ }
+ break;
+ }
+ case SET_VIDEO_HISTOGRAM_STATS: {
+ struct VideoHistogramMetadata *vidstats = (struct VideoHistogramMetadata *)param;
+ if (vidstats->stat_len <= VIDEO_HISTOGRAM_STATS_SIZE) {
+ memcpy(data->video_histogram_stats.stats_info,
+ vidstats->stats_info, VIDEO_HISTOGRAM_STATS_SIZE);
+ data->video_histogram_stats.stat_len = vidstats->stat_len;
+ data->video_histogram_stats.frame_type = vidstats->frame_type;
+ data->video_histogram_stats.display_width = vidstats->display_width;
+ data->video_histogram_stats.display_height = vidstats->display_height;
+ data->video_histogram_stats.decode_width = vidstats->decode_width;
+ data->video_histogram_stats.decode_height = vidstats->decode_height;
+ } else {
+ setGralloc4Array(data, paramType, false);
+ ALOGE("%s: video stats length %u is more than max size %u", __func__,
+ vidstats->stat_len, VIDEO_HISTOGRAM_STATS_SIZE);
+ return -EINVAL;
+ }
+ break;
+ }
+ case SET_VIDEO_TS_INFO:
+ data->videoTsInfo = *((VideoTimestampInfo *)param);
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ break;
+ }
+ return 0;
+}
+
+int clearMetaData(private_handle_t *handle, DispParamType paramType) {
+ auto err = validateAndMap(handle);
+ if (err != 0)
+ return err;
+ return clearMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
+ paramType);
+}
+
+int clearMetaDataVa(MetaData_t *data, DispParamType paramType) {
+ if (data == nullptr)
+ return -EINVAL;
+ data->operation &= ~paramType;
+ switch (paramType) {
+ case SET_VIDEO_PERF_MODE:
+ data->isVideoPerfMode = 0;
+ break;
+ case SET_CVP_METADATA:
+ data->cvpMetadata.size = 0;
+ break;
+ case SET_VIDEO_HISTOGRAM_STATS:
+ data->video_histogram_stats.stat_len = 0;
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ break;
+ }
+ return 0;
+}
+
+int getMetaData(private_handle_t *handle, DispFetchParamType paramType,
+ void *param) {
+ int ret = validateAndMap(handle);
+ if (ret != 0)
+ return ret;
+ return getMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
+ paramType, param);
+}
+
+int getMetaDataVa(MetaData_t *data, DispFetchParamType paramType,
+ void *param) {
+ // Make sure we send 0 only if the operation queried is present
+ int ret = -EINVAL;
+ if (data == nullptr)
+ return ret;
+ if (param == nullptr)
+ return ret;
+
+ if (!getGralloc4Array(data, paramType)) {
+ return ret;
+ }
+
+ ret = 0;
+
+ switch (paramType) {
+ case GET_PP_PARAM_INTERLACED:
+ *((int32_t *)param) = data->interlaced;
+ break;
+ case GET_BUFFER_GEOMETRY:
+ *((BufferDim_t *)param) = {data->crop.right, data->crop.bottom};
+ break;
+ case GET_REFRESH_RATE:
+ *((float *)param) = data->refreshrate;
+ break;
+ case GET_COLOR_SPACE: {
+ ColorSpace_t color_space;
+ if (!colorMetaDataToColorSpace(data->color, &color_space)) {
+ *((ColorSpace_t *)param) = color_space;
+ } else {
+ ret = -EINVAL;
+ }
+ break;
+ }
+ case GET_MAP_SECURE_BUFFER:
+ *((int32_t *)param) = data->mapSecureBuffer;
+ break;
+ case GET_S3D_FORMAT:
+ *((uint32_t *)param) = data->s3dFormat;
+ break;
+ case GET_LINEAR_FORMAT:
+ *((uint32_t *)param) = data->linearFormat;
+ break;
+ case GET_SINGLE_BUFFER_MODE:
+ *((uint32_t *)param) = data->isSingleBufferMode;
+ break;
+ case GET_VT_TIMESTAMP:
+ *((uint64_t *)param) = data->vtTimeStamp;
+ break;
+ case GET_COLOR_METADATA:
+ *((ColorMetaData *)param) = data->color;
+ break;
+ case GET_UBWC_CR_STATS_INFO: {
+ struct UBWCStats *stats = (struct UBWCStats *)param;
+ int numelems = sizeof(data->ubwcCRStats) / sizeof(struct UBWCStats);
+ for (int i = 0; i < numelems; i++) {
+ stats[i] = data->ubwcCRStats[i];
+ }
+ break;
+ }
+ case GET_VIDEO_PERF_MODE:
+ *((uint32_t *)param) = data->isVideoPerfMode;
+ break;
+ case GET_GRAPHICS_METADATA:
+ memcpy(param, data->graphics_metadata.data, sizeof(data->graphics_metadata.data));
+ break;
+ case GET_CVP_METADATA: {
+ struct CVPMetadata *cvpMetadata = (struct CVPMetadata *)param;
+ cvpMetadata->size = 0;
+ if (data->cvpMetadata.size <= CVP_METADATA_SIZE) {
+ cvpMetadata->size = data->cvpMetadata.size;
+ memcpy(cvpMetadata->payload, data->cvpMetadata.payload, data->cvpMetadata.size);
+ cvpMetadata->capture_frame_rate = data->cvpMetadata.capture_frame_rate;
+ cvpMetadata->cvp_frame_rate = data->cvpMetadata.cvp_frame_rate;
+ cvpMetadata->flags = data->cvpMetadata.flags;
+ memcpy(cvpMetadata->reserved, data->cvpMetadata.reserved, (8 * sizeof(uint32_t)));
+ } else {
+ ret = -EINVAL;
+ }
+ break;
+ }
+ case GET_VIDEO_HISTOGRAM_STATS: {
+ struct VideoHistogramMetadata *vidstats = (struct VideoHistogramMetadata *)param;
+ vidstats->stat_len = 0;
+ if (data->video_histogram_stats.stat_len <= VIDEO_HISTOGRAM_STATS_SIZE) {
+ memcpy(vidstats->stats_info, data->video_histogram_stats.stats_info,
+ VIDEO_HISTOGRAM_STATS_SIZE);
+ vidstats->stat_len = data->video_histogram_stats.stat_len;
+ vidstats->frame_type = data->video_histogram_stats.frame_type;
+ vidstats->display_width = data->video_histogram_stats.display_width;
+ vidstats->display_height = data->video_histogram_stats.display_height;
+ vidstats->decode_width = data->video_histogram_stats.decode_width;
+ vidstats->decode_height = data->video_histogram_stats.decode_height;
+ } else {
+ ret = -EINVAL;
+ }
+ break;
+ }
+ case GET_VIDEO_TS_INFO:
+ *((VideoTimestampInfo *)param) = data->videoTsInfo;
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+int copyMetaData(struct private_handle_t *src, struct private_handle_t *dst) {
+ auto err = validateAndMap(src);
+ if (err != 0)
+ return err;
+
+ err = validateAndMap(dst);
+ if (err != 0)
+ return err;
+
+ MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
+ MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
+ *dst_data = *src_data;
+ return 0;
+}
+
+int copyMetaDataVaToHandle(MetaData_t *src_data, struct private_handle_t *dst) {
+ int err = -EINVAL;
+ if (src_data == nullptr)
+ return err;
+
+ err = validateAndMap(dst);
+ if (err != 0)
+ return err;
+
+ MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
+ *dst_data = *src_data;
+ return 0;
+}
+
+int copyMetaDataHandleToVa(struct private_handle_t *src, MetaData_t *dst_data) {
+ int err = -EINVAL;
+ if (dst_data == nullptr)
+ return err;
+
+ err = validateAndMap(src);
+ if (err != 0)
+ return err;
+
+ MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
+ *dst_data = *src_data;
+ return 0;
+}
+
+int copyMetaDataVaToVa(MetaData_t *src_data, MetaData_t *dst_data) {
+ int err = -EINVAL;
+ if (src_data == nullptr)
+ return err;
+
+ if (dst_data == nullptr)
+ return err;
+
+ *dst_data = *src_data;
+ return 0;
+}
+
+int setMetaDataAndUnmap(struct private_handle_t *handle, enum DispParamType paramType,
+ void *param) {
+ auto ret = setMetaData(handle, paramType, param);
+ unmapAndReset(handle);
+ return ret;
+}
+
+int getMetaDataAndUnmap(struct private_handle_t *handle,
+ enum DispFetchParamType paramType,
+ void *param) {
+ auto ret = getMetaData(handle, paramType, param);
+ unmapAndReset(handle);
+ return ret;
+}
diff --git a/libqdmetadata/qd_utils.cpp b/libqdmetadata/qd_utils.cpp
new file mode 100644
index 0000000..ac5d094
--- /dev/null
+++ b/libqdmetadata/qd_utils.cpp
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2013, 2018, 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 <unistd.h>
+#include <gralloc_priv.h>
+#include "qd_utils.h"
+
+static const int kFBNodeMax = 4;
+namespace qdutils {
+
+static int parseLine(char *input, char *tokens[], const uint32_t maxToken, uint32_t *count) {
+ char *tmpToken = NULL;
+ char *tmpPtr;
+ uint32_t index = 0;
+ const char *delim = ", =\n";
+ if (!input) {
+ return -1;
+ }
+ tmpToken = strtok_r(input, delim, &tmpPtr);
+ while (tmpToken && index < maxToken) {
+ tokens[index++] = tmpToken;
+ tmpToken = strtok_r(NULL, delim, &tmpPtr);
+ }
+ *count = index;
+
+ return 0;
+}
+
+static int getExternalNode(const char *type) {
+ FILE *displayDeviceFP = NULL;
+ char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
+ char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
+ int j = 0;
+
+ for(j = 0; j < kFBNodeMax; j++) {
+ snprintf (msmFbTypePath, sizeof(msmFbTypePath),
+ "/sys/devices/virtual/graphics/fb%d/msm_fb_type", j);
+ displayDeviceFP = fopen(msmFbTypePath, "r");
+ if(displayDeviceFP) {
+ fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
+ displayDeviceFP);
+ if(strncmp(fbType, type, strlen(type)) == 0) {
+ ALOGD("%s: %s is at fb%d", __func__, type, j);
+ fclose(displayDeviceFP);
+ break;
+ }
+ fclose(displayDeviceFP);
+ } else {
+ ALOGE("%s: Failed to open fb node %s", __func__, msmFbTypePath);
+ }
+ }
+
+ if (j < kFBNodeMax)
+ return j;
+ else
+ ALOGE("%s: Failed to find %s node", __func__, type);
+
+ return -1;
+}
+
+int getHDMINode(void) {
+ return getExternalNode("dtv panel");
+}
+
+int getEdidRawData(char *buffer)
+{
+ int size;
+ int edidFile;
+ char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
+ int node_id = getHDMINode();
+
+ if (node_id < 0) {
+ ALOGE("%s no HDMI node found", __func__);
+ return 0;
+ }
+
+ snprintf(msmFbTypePath, sizeof(msmFbTypePath),
+ "/sys/devices/virtual/graphics/fb%d/edid_raw_data", node_id);
+
+ edidFile = open(msmFbTypePath, O_RDONLY, 0);
+
+ if (edidFile < 0) {
+ ALOGE("%s no edid raw data found %s", __func__,msmFbTypePath);
+ return 0;
+ }
+
+ size = (int)read(edidFile, (char*)buffer, EDID_RAW_DATA_SIZE);
+ close(edidFile);
+ return size;
+}
+
+bool isDPConnected() {
+ char connectPath[MAX_FRAME_BUFFER_NAME_SIZE];
+ FILE *connectFile = NULL;
+ size_t len = MAX_STRING_LENGTH;
+ char stringBuffer[MAX_STRING_LENGTH];
+ char *line = stringBuffer;
+
+ int nodeId = getExternalNode("dp panel");
+ if (nodeId < 0) {
+ ALOGE("%s no DP node found", __func__);
+ return false;
+ }
+
+ snprintf(connectPath, sizeof(connectPath),
+ "/sys/devices/virtual/graphics/fb%d/connected", nodeId);
+
+ connectFile = fopen(connectPath, "rb");
+ if (!connectFile) {
+ ALOGW("Failed to open connect node for device node %s", connectPath);
+ return false;
+ }
+
+ if (getline(&line, &len, connectFile) < 0) {
+ fclose(connectFile);
+ return false;
+ }
+
+ fclose(connectFile);
+
+ return atoi(line);
+}
+
+int getDPTestConfig(uint32_t *panelBpp, uint32_t *patternType) {
+ if (!panelBpp || !patternType) {
+ return -1;
+ }
+
+ char configPath[MAX_FRAME_BUFFER_NAME_SIZE];
+ FILE *configFile = NULL;
+ uint32_t tokenCount = 0;
+ const uint32_t maxCount = 10;
+ char *tokens[maxCount] = { NULL };
+ size_t len = MAX_STRING_LENGTH;
+ char stringBuffer[MAX_STRING_LENGTH];
+ char *line = stringBuffer;
+
+ int nodeId = getExternalNode("dp panel");
+ if (nodeId < 0) {
+ ALOGE("%s no DP node found", __func__);
+ return -EINVAL;
+ }
+
+ snprintf(configPath, sizeof(configPath),
+ "/sys/devices/virtual/graphics/fb%d/config", nodeId);
+
+ configFile = fopen(configPath, "rb");
+ if (!configFile) {
+ ALOGW("Failed to open config node for device node %s", configPath);
+ return -EINVAL;
+ }
+
+ while (getline(&line, &len, configFile) != -1) {
+ if (!parseLine(line, tokens, maxCount, &tokenCount)) {
+ if (tokens[0] != NULL) {
+ if (!strncmp(tokens[0], "bpp", strlen("bpp"))) {
+ *panelBpp = static_cast<uint32_t>(atoi(tokens[1]));
+ } else if (!strncmp(tokens[0], "pattern", strlen("pattern"))) {
+ *patternType = static_cast<uint32_t>(atoi(tokens[1]));
+ }
+ }
+ }
+ }
+
+ fclose(configFile);
+
+ return 0;
+}
+
+DriverType getDriverType() {
+ const char *fb_caps = "/sys/devices/virtual/graphics/fb0/mdp/caps";
+ // 0 - File exists
+ return access(fb_caps, F_OK) ? DriverType::DRM : DriverType::FB;
+}
+
+const char *GetHALPixelFormatString(int format) {
+ switch (format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ return "RGBA_8888";
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ return "RGBX_8888";
+ case HAL_PIXEL_FORMAT_RGB_888:
+ return "RGB_888";
+ case HAL_PIXEL_FORMAT_RGB_565:
+ return "RGB_565";
+ case HAL_PIXEL_FORMAT_BGR_565:
+ return "BGR_565";
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ return "BGRA_8888";
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ return "RGBA_5551";
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ return "RGBA_4444";
+ case HAL_PIXEL_FORMAT_YV12:
+ return "YV12";
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ return "YCbCr_422_SP_NV16";
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ return "YCrCb_420_SP_NV21";
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ return "YCbCr_422_I_YUY2";
+ case HAL_PIXEL_FORMAT_YCrCb_422_I:
+ return "YCrCb_422_I_YVYU";
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ return "NV12_ENCODEABLE";
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+ return "YCbCr_420_SP_TILED_TILE_4x2";
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ return "YCbCr_420_SP";
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+ return "YCrCb_420_SP_ADRENO";
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ return "YCrCb_422_SP";
+ case HAL_PIXEL_FORMAT_R_8:
+ return "R_8";
+ case HAL_PIXEL_FORMAT_RG_88:
+ return "RG_88";
+ case HAL_PIXEL_FORMAT_INTERLACE:
+ return "INTERLACE";
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ return "YCbCr_420_SP_VENUS";
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+ return "YCrCb_420_SP_VENUS";
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ return "YCbCr_420_SP_VENUS_UBWC";
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ return "RGBA_1010102";
+ case HAL_PIXEL_FORMAT_ARGB_2101010:
+ return "ARGB_2101010";
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ return "RGBX_1010102";
+ case HAL_PIXEL_FORMAT_XRGB_2101010:
+ return "XRGB_2101010";
+ case HAL_PIXEL_FORMAT_BGRA_1010102:
+ return "BGRA_1010102";
+ case HAL_PIXEL_FORMAT_ABGR_2101010:
+ return "ABGR_2101010";
+ case HAL_PIXEL_FORMAT_BGRX_1010102:
+ return "BGRX_1010102";
+ case HAL_PIXEL_FORMAT_XBGR_2101010:
+ return "XBGR_2101010";
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ return "YCbCr_420_P010";
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+ return "YCbCr_420_TP10_UBWC";
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
+ return "YCbCr_420_P010_VENUS";
+ default:
+ return "Unknown_format";
+ }
+}
+
+}; //namespace qdutils
diff --git a/services/config/src/Android.bp b/services/config/src/Android.bp
new file mode 100644
index 0000000..307f773
--- /dev/null
+++ b/services/config/src/Android.bp
@@ -0,0 +1,24 @@
+cc_library_shared {
+ name: "libdisplayconfig.system.qti",
+ system_ext_specific: true,
+ cflags: [
+ "-Wno-sign-conversion",
+ "-Wno-unused-parameter",
+ "-DLOG_TAG=\"libdisplayconfigqti\"",
+ ],
+ shared_libs: [
+ "liblog",
+ "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..ad0b1fb
--- /dev/null
+++ b/services/config/src/client_impl.cpp
@@ -0,0 +1,1066 @@
+/*
+* Copyright (c) 2020-2021 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();
+ android::sp<ClientCallback> client_cb(new ClientCallback(callback));
+ display_config_->registerClient(client_name + std::to_string(pid), client_cb,
+ hidl_callback);
+ client_handle_ = handle;
+
+ return 0;
+}
+
+void ClientImpl::DeInit() {
+ int32_t error = 0;
+ auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+ error = err;
+ };
+
+ display_config_->perform(client_handle_, kDestroy, {}, {}, hidl_cb);
+ display_config_.clear();
+ display_config_ = nullptr;
+}
+
+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) {
+ if (!config) {
+ return -EINVAL;
+ }
+
+ 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;
+ };
+
+ if (display_config_) {
+ display_config_->perform(client_handle_, kGetActiveConfig, input_params, {}, hidl_cb);
+ }
+
+ if (!error) {
+ 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;
+ std::string prop(prop_name);
+ prop += '\0';
+ uint8_t *data_input = reinterpret_cast<uint8_t*>(const_cast<char*>(prop.data()));
+ input_params.setToExternal(reinterpret_cast<uint8_t*>(data_input),
+ prop.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);
+ if (!error) {
+ std::string output(name);
+ *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) {
+ 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;
+}
+
+int ClientImpl::ControlIdleStatusCallback(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_, kControlIdleStatusCallback, input_params, {}, hidl_cb);
+
+ return error;
+}
+
+int ClientImpl::SendTUIEvent(DisplayType dpy, TUIEventType event_type) {
+ struct TUIEventParams input = {dpy, event_type};
+ ByteStream input_params;
+ input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct TUIEventParams));
+ int32_t error = 0;
+ auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+ error = err;
+ };
+
+ display_config_->perform(client_handle_, kSendTUIEvent, input_params, {}, hidl_cb);
+
+ return error;
+}
+
+int ClientImpl::GetDisplayHwId(uint32_t disp_id, uint32_t *display_hw_id) {
+ 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_, kGetDisplayHwId, input_params, {}, hidl_cb);
+
+ const uint8_t *data = output_params.data();
+ const uint32_t *output = reinterpret_cast<const uint32_t*>(data);
+
+ if (!error) {
+ *display_hw_id = *output;
+ }
+
+ return error;
+}
+
+int ClientImpl::GetSupportedDisplayRefreshRates(DisplayType dpy,
+ std::vector<uint32_t> *supported_refresh_rates) {
+ 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_, kGetSupportedDisplayRefreshRates, input_params, {},
+ hidl_cb);
+
+ if (!error) {
+ const uint8_t *data = output_params.data();
+ const uint32_t *refresh_rates_data = reinterpret_cast<const uint32_t *>(data);
+ int num_refresh_rates = static_cast<int>(output_params.size() / sizeof(uint32_t));
+ for (int i = 0; i < num_refresh_rates; i++) {
+ supported_refresh_rates->push_back(refresh_rates_data[i]);
+ }
+ }
+
+ return error;
+}
+
+int ClientImpl::IsRCSupported(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_, kIsRCSupported, input_params, {}, hidl_cb);
+
+ if (!error) {
+ const uint8_t *data = output_params.data();
+ output = reinterpret_cast<const bool*>(data);
+ *supported = *output;
+ }
+
+ return error;
+}
+
+int ClientImpl::DummyDisplayConfigAPI() {
+ int error = 0;
+ auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+ error = err;
+ };
+ display_config_->perform(client_handle_, kDummyOpcode, {}, {}, hidl_cb);
+ if (error) {
+ return -EINVAL;
+ }
+ return error;
+}
+
+int ClientImpl::IsSupportedConfigSwitch(uint32_t disp_id, uint32_t config, bool *supported) {
+ struct SupportedModesParams input = {disp_id, config};
+ ByteStream input_params;
+ ByteStream output_params;
+ const bool *output;
+ input_params.setToExternal(reinterpret_cast<uint8_t*>(&input),
+ sizeof(struct SupportedModesParams));
+ int error = 0;
+ auto hidl_cb = [&error, &output_params] (int32_t err, ByteStream params, HandleStream handles) {
+ error = err;
+ output_params = params;
+ };
+ if (display_config_) {
+ display_config_->perform(client_handle_, kIsSupportedConfigSwitch, input_params, {}, hidl_cb);
+ }
+
+ if (!error) {
+ const uint8_t *data = output_params.data();
+ output = reinterpret_cast<const bool *>(data);
+ *supported = *output;
+ }
+
+ return error;
+}
+
+int ClientImpl::GetDisplayType(uint64_t physical_disp_id, DisplayType *disp_type) {
+ if (!disp_type) {
+ return -EINVAL;
+ }
+ ByteStream input_params;
+ input_params.setToExternal(reinterpret_cast<uint8_t*>(&physical_disp_id), sizeof(uint64_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;
+ };
+ if (display_config_) {
+ display_config_->perform(client_handle_, kGetDisplayType, input_params, {}, hidl_cb);
+ }
+
+ if (!error) {
+ const uint8_t *data = output_params.data();
+ const DisplayType *output = reinterpret_cast<const DisplayType*>(data);
+ *disp_type = *output;
+ }
+ return error;
+}
+
+int ClientImpl::AllowIdleFallback() {
+ int error = 0;
+ auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+ error = err;
+ };
+ if (display_config_) {
+ display_config_->perform(client_handle_, kAllowIdleFallback, {}, {}, hidl_cb);
+ }
+ return error;
+}
+
+void ClientCallback::ParseNotifyCWBBufferDone(const ByteStream &input_params,
+ const HandleStream &input_handles) {
+ const int *error;
+
+ if (callback_ == nullptr || 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 ClientCallback::ParseNotifyQsyncChange(const ByteStream &input_params) {
+ const struct QsyncCallbackParams *qsync_data;
+
+ if (callback_ == nullptr || 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);
+}
+
+void ClientCallback::ParseNotifyIdleStatus(const ByteStream &input_params) {
+ const bool *is_idle;
+ if (callback_ == nullptr || input_params.size() == 0) {
+ return;
+ }
+
+ const uint8_t *data = input_params.data();
+ is_idle = reinterpret_cast<const bool*>(data);
+ callback_->NotifyIdleStatus(*is_idle);
+}
+
+Return<void> ClientCallback::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;
+ case kControlIdleStatusCallback:
+ ParseNotifyIdleStatus(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..48b543a
--- /dev/null
+++ b/services/config/src/client_impl.h
@@ -0,0 +1,139 @@
+/*
+* Copyright (c) 2020-2021 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__
+
+#define VALIDATE_CONFIG_SWITCH 1
+
+#include <vendor/display/config/2.0/IDisplayConfig.h>
+#include <hidl/HidlSupport.h>
+#include <log/log.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 ClientCallback: public IDisplayConfigCallback {
+ public:
+ ClientCallback(ConfigCallback *cb) {
+ callback_ = cb;
+ }
+
+ 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);
+ void ParseNotifyIdleStatus(const ByteStream &input_params);
+ ConfigCallback *callback_ = nullptr;
+};
+
+class ClientImpl : public ClientInterface {
+ public:
+ int Init(std::string client_name, ConfigCallback *callback);
+ void DeInit();
+
+ 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);
+ virtual int SendTUIEvent(DisplayType dpy, TUIEventType event_type);
+ virtual int GetDisplayHwId(uint32_t disp_id, uint32_t *display_hw_id);
+ virtual int GetSupportedDisplayRefreshRates(DisplayType dpy,
+ std::vector<uint32_t> *supported_refresh_rates);
+ virtual int IsRCSupported(uint32_t disp_id, bool *supported);
+ virtual int ControlIdleStatusCallback(bool enable);
+ virtual int IsSupportedConfigSwitch(uint32_t disp_id, uint32_t config, bool *supported);
+ virtual int GetDisplayType(uint64_t physical_disp_id, DisplayType *disp_type);
+ virtual int AllowIdleFallback();
+ virtual int DummyDisplayConfigAPI();
+
+ private:
+ android::sp<IDisplayConfig> display_config_ = 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..9c9ecd2
--- /dev/null
+++ b/services/config/src/client_interface.cpp
@@ -0,0 +1,65 @@
+/*
+* 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) {
+ ClientImpl *impl = static_cast<ClientImpl *>(intf);
+ impl->DeInit();
+ delete impl;
+ }
+}
+
+} // namespace DisplayConfig
diff --git a/services/config/src/device_impl.cpp b/services/config/src/device_impl.cpp
new file mode 100644
index 0000000..df4731f
--- /dev/null
+++ b/services/config/src/device_impl.cpp
@@ -0,0 +1,1040 @@
+/*
+* Copyright (c) 2020-2021 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) {
+ ALOGI("Register client:%s", client_name.c_str());
+ 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();
+ }
+
+ if (!callback) {
+ ALOGW("IDisplayConfigCallback provided is null");
+ }
+
+ 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);
+ }
+
+ if (!intf_) {
+ ALOGW("ConfigInterface is invalid");
+ _hidl_cb(error, 0);
+ return Void();
+ }
+
+ if (!device_client) {
+ ALOGW("Failed to initialize device client:%s", client_name.c_str());
+ _hidl_cb(error, 0);
+ return Void();
+ }
+
+ ConfigInterface *intf = nullptr;
+ error = intf_->RegisterClientContext(device_client, &intf);
+
+ if (error) {
+ callback->unlinkToDeath(this);
+ return Void();
+ }
+
+ 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;
+ if (client != NULL) {
+ ConfigInterface *intf = client->GetDeviceConfigIntf();
+ intf_->UnRegisterClientContext(intf);
+ client.reset();
+ display_config_map_.erase(itr);
+ }
+}
+
+DeviceImpl::DeviceClientContext::DeviceClientContext(
+ const sp<IDisplayConfigCallback> callback) : callback_(callback) { }
+
+sp<IDisplayConfigCallback> DeviceImpl::DeviceClientContext::GetDeviceConfigCallback() {
+ return 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::NotifyIdleStatus(bool is_idle) {
+ bool data = {is_idle};
+ ByteStream output_params;
+
+ output_params.setToExternal(reinterpret_cast<uint8_t*>(&data), sizeof(data));
+
+ auto status = callback_->perform(kControlIdleStatusCallback, 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)));
+ if (data_output != NULL) {
+ 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, {});
+ }
+ else {
+ _hidl_cb(-EINVAL, {}, {});
+ }
+}
+
+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 = false;
+ int32_t error = intf_->GetWriteBackCapabilities(&is_wb_ubwc_supported);
+ ByteStream output_params;
+ 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 uint8_t *data = input_params.data();
+ const uint32_t *disp_id = reinterpret_cast<const uint32_t*>(data);
+ bool supported = false;
+ int32_t error = intf_->IsPowerModeOverrideSupported(*disp_id, &supported);
+ ByteStream output_params;
+ 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 uint8_t *data = input_params.data();
+ const uint32_t *disp_id = reinterpret_cast<const uint32_t*>(data);
+ bool supported = false;
+ int32_t error = intf_->IsHDRSupported(*disp_id, &supported);
+ ByteStream output_params;
+ 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 uint8_t *data = input_params.data();
+ const int32_t *disp_id = reinterpret_cast<const int32_t*>(data);
+ bool supported = false;
+ int32_t error = intf_->IsWCGSupported(*disp_id, &supported);
+ ByteStream output_params;
+ 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);
+ value += '\0';
+ 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()));
+ if (bit_clks_data == NULL) {
+ _hidl_cb(-EINVAL, {}, {});
+ return;
+ }
+ 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 = false;
+ int32_t error = intf_->IsAsyncVDSCreationSupported(&is_supported);
+ ByteStream output_params;
+ 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, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseControlIdleStatusCallback(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_->ControlIdleStatusCallback(*enable);
+
+ _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseSendTUIEvent(const ByteStream &input_params,
+ perform_cb _hidl_cb) {
+ const struct TUIEventParams *input_data =
+ reinterpret_cast<const TUIEventParams*>(input_params.data());
+
+ int32_t error = intf_->SendTUIEvent(input_data->dpy, input_data->tui_event_type);
+
+ _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::ParseDestroy(uint64_t client_handle, perform_cb _hidl_cb) {
+ auto itr = display_config_map_.find(client_handle);
+ if (itr == display_config_map_.end()) {
+ _hidl_cb(-EINVAL, {}, {});
+ return;
+ }
+
+ std::shared_ptr<DeviceClientContext> client = itr->second;
+ if (client != NULL) {
+ sp<IDisplayConfigCallback> callback = client->GetDeviceConfigCallback();
+ callback->unlinkToDeath(this);
+ ConfigInterface *intf = client->GetDeviceConfigIntf();
+ intf_->UnRegisterClientContext(intf);
+ client.reset();
+ display_config_map_.erase(itr);
+ }
+
+ _hidl_cb(0, {}, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetDisplayHwId(const ByteStream &input_params,
+ perform_cb _hidl_cb) {
+ uint32_t disp_hw_id = 0;
+ ByteStream output_params;
+
+ const uint8_t *data = input_params.data();
+ const uint32_t *disp_id = reinterpret_cast<const uint32_t*>(data);
+ int32_t error = intf_->GetDisplayHwId(*disp_id, &disp_hw_id);
+ output_params.setToExternal(reinterpret_cast<uint8_t*>(&disp_hw_id), sizeof(uint32_t));
+
+ _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetSupportedDisplayRefreshRates(
+ const ByteStream &input_params, perform_cb _hidl_cb) {
+ ByteStream output_params;
+ std::vector<uint32_t> refresh_rates;
+
+ const uint8_t *data = input_params.data();
+ const DisplayType *dpy = reinterpret_cast<const DisplayType *>(data);
+ int32_t error = intf_->GetSupportedDisplayRefreshRates(*dpy, &refresh_rates);
+
+ uint32_t *refresh_rates_data =
+ reinterpret_cast<uint32_t *>(malloc(sizeof(uint32_t) * refresh_rates.size()));
+ if (refresh_rates_data) {
+ for (int i = 0; i < refresh_rates.size(); i++) {
+ refresh_rates_data[i] = refresh_rates[i];
+ }
+ output_params.setToExternal(reinterpret_cast<uint8_t *>(refresh_rates_data),
+ sizeof(uint32_t) * refresh_rates.size());
+ _hidl_cb(error, output_params, {});
+ } else {
+ _hidl_cb(-EINVAL, {}, {});
+ }
+}
+
+void DeviceImpl::DeviceClientContext::ParseIsRCSupported(const ByteStream &input_params,
+ perform_cb _hidl_cb) {
+ const uint8_t *data = input_params.data();
+ const uint32_t *disp_id = reinterpret_cast<const uint32_t*>(data);
+ bool supported = false;
+ int32_t error = intf_->IsRCSupported(*disp_id, &supported);
+ ByteStream output_params;
+ output_params.setToExternal(reinterpret_cast<uint8_t*>(&supported), sizeof(bool));
+
+ _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseIsSupportedConfigSwitch(const ByteStream &input_params,
+ perform_cb _hidl_cb) {
+ if (!intf_) {
+ _hidl_cb(-EINVAL, {}, {});
+ return;
+ }
+
+ const struct SupportedModesParams *supported_modes_data;
+ const uint8_t *data = input_params.data();
+ bool supported = false;
+ ByteStream output_params;
+ supported_modes_data = reinterpret_cast<const SupportedModesParams*>(data);
+
+ int32_t error = intf_->IsSupportedConfigSwitch(supported_modes_data->disp_id,
+ supported_modes_data->mode, &supported);
+ output_params.setToExternal(reinterpret_cast<uint8_t*>(&supported), sizeof(bool));
+ _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseGetDisplayType(const ByteStream &input_params,
+ perform_cb _hidl_cb) {
+ const uint8_t *data = input_params.data();
+ const uint64_t *physical_disp_id = reinterpret_cast<const uint64_t*>(data);
+ DisplayType disp_type = DisplayConfig::DisplayType::kInvalid;
+ int32_t error = intf_->GetDisplayType(*physical_disp_id, &disp_type);
+ ByteStream output_params;
+ output_params.setToExternal(reinterpret_cast<uint8_t*>(&disp_type), sizeof(DisplayType));
+
+ _hidl_cb(error, output_params, {});
+}
+
+void DeviceImpl::DeviceClientContext::ParseAllowIdleFallback(perform_cb _hidl_cb) {
+ int32_t error = intf_->AllowIdleFallback();
+ _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;
+ if (!client) {
+ error = -EINVAL;
+ _hidl_cb(error, {}, {});
+ return Void();
+ }
+ 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;
+ case kControlIdleStatusCallback:
+ client->ParseControlIdleStatusCallback(client_handle, input_params, _hidl_cb);
+ break;
+ case kSendTUIEvent:
+ client->ParseSendTUIEvent(input_params, _hidl_cb);
+ break;
+ case kDestroy:
+ ParseDestroy(client_handle, _hidl_cb);
+ break;
+ case kGetDisplayHwId:
+ client->ParseGetDisplayHwId(input_params, _hidl_cb);
+ break;
+ case kGetSupportedDisplayRefreshRates:
+ client->ParseGetSupportedDisplayRefreshRates(input_params, _hidl_cb);
+ break;
+ case kIsRCSupported:
+ client->ParseIsRCSupported(input_params, _hidl_cb);
+ break;
+ case kIsSupportedConfigSwitch:
+ client->ParseIsSupportedConfigSwitch(input_params, _hidl_cb);
+ break;
+ case kGetDisplayType:
+ client->ParseGetDisplayType(input_params, _hidl_cb);
+ break;
+ case kAllowIdleFallback:
+ client->ParseAllowIdleFallback(_hidl_cb);
+ break;
+ case kDummyOpcode:
+ _hidl_cb(-EINVAL, {}, {});
+ break;
+ default:
+ _hidl_cb(-EINVAL, {}, {});
+ 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..4c22a47
--- /dev/null
+++ b/services/config/src/device_impl.h
@@ -0,0 +1,153 @@
+/*
+* Copyright (c) 2021 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 <log/log.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();
+ sp<IDisplayConfigCallback> GetDeviceConfigCallback();
+
+ 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);
+ virtual void NotifyIdleStatus(bool is_idle);
+
+ 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);
+ void ParseSendTUIEvent(const ByteStream &input_params, perform_cb _hidl_cb);
+ void ParseGetDisplayHwId(const ByteStream &input_params, perform_cb _hidl_cb);
+ void ParseGetSupportedDisplayRefreshRates(const ByteStream &input_params, perform_cb _hidl_cb);
+ void ParseIsRCSupported(const ByteStream &input_params, perform_cb _hidl_cb);
+ void ParseControlIdleStatusCallback(uint64_t client_handle, const ByteStream &input_params,
+ perform_cb _hidl_cb);
+ void ParseIsSupportedConfigSwitch(const ByteStream &input_params, perform_cb _hidl_cb);
+ void ParseGetDisplayType(const ByteStream &input_params, perform_cb _hidl_cb);
+ void ParseAllowIdleFallback(perform_cb _hidl_cb);
+
+ private:
+ ConfigInterface *intf_ = nullptr;
+ const 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);
+ void ParseDestroy(uint64_t client_handle, perform_cb _hidl_cb);
+
+ 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..4813e47
--- /dev/null
+++ b/services/config/src/opcode_types.h
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2020-2021 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,
+ kSendTUIEvent = 42,
+ kGetDisplayHwId = 43,
+ kGetSupportedDisplayRefreshRates = 44,
+ kIsRCSupported = 45,
+ kControlIdleStatusCallback = 46,
+ kIsSupportedConfigSwitch = 47,
+ kGetDisplayType = 48,
+ kAllowIdleFallback = 49,
+ kDummyOpcode = 50,
+
+ kDestroy = 0xFFFF, // Destroy sequence execution
+};
+
+} // namespace DisplayConfig
+
+#endif // __OPCODE_TYPES_H__