hwc2: Implement IDisplayConfig HIDL service.

- Add IDisplayConfig service in composer process.
- Add DisplayConfig wrapper to abstract
  IDisplayConfig interfaces.

CRs-Fixed: 2036340
Change-Id: I54535e7224ee842b761509268ebaa2e8425bc8d7
diff --git a/libdisplayconfig/DisplayConfig.cpp b/libdisplayconfig/DisplayConfig.cpp
new file mode 100644
index 0000000..c55715b
--- /dev/null
+++ b/libdisplayconfig/DisplayConfig.cpp
@@ -0,0 +1,363 @@
+/*
+* Copyright (c) 2017 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 <vendor/display/config/1.0/IDisplayConfig.h>
+
+#include "DisplayConfig.h"
+
+namespace display {
+
+using vendor::display::config::V1_0::IDisplayConfig;
+
+//=============================================================================
+// The functions below run in the client process and wherever necessary
+// do a binder call to HWC to get/set data.
+
+IDisplayConfig::DisplayType MapDisplayType(int dpy) {
+    switch (dpy) {
+        case DISPLAY_PRIMARY:
+            return IDisplayConfig::DisplayType::DISPLAY_PRIMARY;
+
+        case DISPLAY_EXTERNAL:
+            return IDisplayConfig::DisplayType::DISPLAY_EXTERNAL;
+
+        case DISPLAY_VIRTUAL:
+            return IDisplayConfig::DisplayType::DISPLAY_VIRTUAL;
+
+        default:
+            break;
+    }
+
+    return IDisplayConfig::DisplayType::INVALID;
+}
+
+IDisplayConfig::DisplayExternalStatus MapExternalStatus(uint32_t status) {
+    switch (status) {
+        case EXTERNAL_OFFLINE:
+            return IDisplayConfig::DisplayExternalStatus::EXTERNAL_OFFLINE;
+
+        case EXTERNAL_ONLINE:
+            return IDisplayConfig::DisplayExternalStatus::EXTERNAL_ONLINE;
+
+        case EXTERNAL_PAUSE:
+            return IDisplayConfig::DisplayExternalStatus::EXTERNAL_PAUSE;
+
+        case EXTERNAL_RESUME:
+            return IDisplayConfig::DisplayExternalStatus::EXTERNAL_RESUME;
+
+        default:
+            break;
+    }
+
+    return IDisplayConfig::DisplayExternalStatus::INVALID;
+}
+
+IDisplayConfig::DisplayDynRefreshRateOp MapDynRefreshRateOp(uint32_t op) {
+    switch (op) {
+        case DISABLE_METADATA_DYN_REFRESH_RATE:
+            return IDisplayConfig::DisplayDynRefreshRateOp::DISABLE_METADATA_DYN_REFRESH_RATE;
+
+        case ENABLE_METADATA_DYN_REFRESH_RATE:
+            return IDisplayConfig::DisplayDynRefreshRateOp::ENABLE_METADATA_DYN_REFRESH_RATE;
+
+        case SET_BINDER_DYN_REFRESH_RATE:
+            return IDisplayConfig::DisplayDynRefreshRateOp::SET_BINDER_DYN_REFRESH_RATE;
+
+        default:
+            break;
+    }
+
+    return IDisplayConfig::DisplayDynRefreshRateOp::INVALID;
+}
+
+int MapDisplayPortType(IDisplayConfig::DisplayPortType panelType) {
+    switch (panelType) {
+        case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DEFAULT:
+            return DISPLAY_PORT_DEFAULT;
+
+        case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DSI:
+            return DISPLAY_PORT_DSI;
+
+        case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DTV:
+            return DISPLAY_PORT_DTV;
+
+        case IDisplayConfig::DisplayPortType::DISPLAY_PORT_WRITEBACK:
+            return DISPLAY_PORT_WRITEBACK;
+
+        case IDisplayConfig::DisplayPortType::DISPLAY_PORT_LVDS:
+            return DISPLAY_PORT_LVDS;
+
+        case IDisplayConfig::DisplayPortType::DISPLAY_PORT_EDP:
+            return DISPLAY_PORT_EDP;
+
+        case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DP:
+            return DISPLAY_PORT_DP;
+
+        default:
+            break;
+    }
+
+    return -1;
+}
+
+int isExternalConnected() {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return 0;
+    }
+
+    int connected = 0;
+    intf->isDisplayConnected(IDisplayConfig::DisplayType::DISPLAY_EXTERNAL,
+        [&](const auto &tmpError, const auto &tmpStatus) {
+            if (tmpError) {
+                return;
+            }
+
+            connected = tmpStatus;
+        });
+
+    return connected;
+}
+
+int setSecondayDisplayStatus(int dpy, uint32_t status) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    return intf->setSecondayDisplayStatus(MapDisplayType(dpy), MapExternalStatus(status));
+}
+
+int configureDynRefeshRate(uint32_t op, uint32_t refreshRate) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    return intf->configureDynRefeshRate(MapDynRefreshRateOp(op), refreshRate);
+}
+
+int getConfigCount(int dpy) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    int count = 0;
+    intf->getActiveConfig(MapDisplayType(dpy),
+        [&](const auto &tmpError, const auto &tmpCount) {
+            if (tmpError) {
+                return;
+            }
+
+            count = tmpCount;
+        });
+
+    return count;
+}
+
+int getActiveConfig(int dpy) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    int config = 0;
+    intf->getActiveConfig(MapDisplayType(dpy),
+        [&](const auto &tmpError, const auto &tmpConfig) {
+            if (tmpError) {
+                return;
+            }
+
+            config = tmpConfig;
+        });
+
+    return config;
+}
+
+int setActiveConfig(int dpy, uint32_t config) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    return intf->setActiveConfig(MapDisplayType(dpy), config);
+}
+
+DisplayAttributes getDisplayAttributes(uint32_t configIndex, int dpy) {
+    DisplayAttributes attributes;
+
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return attributes;
+    }
+
+    intf->getDisplayAttributes(configIndex, MapDisplayType(dpy),
+        [&](const auto &tmpError, const auto &tmpAttributes) {
+            if (tmpError) {
+                return;
+            }
+
+            attributes.vsync_period = tmpAttributes.vsyncPeriod;
+            attributes.xres = tmpAttributes.xRes;
+            attributes.yres = tmpAttributes.yRes;
+            attributes.xdpi = tmpAttributes.xDpi;
+            attributes.ydpi = tmpAttributes.yDpi;
+            attributes.panel_type = MapDisplayPortType(tmpAttributes.panelType);
+            attributes.is_yuv = tmpAttributes.isYuv;
+        });
+
+    return attributes;
+}
+
+int setPanelBrightness(uint32_t level) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    return intf->setPanelBrightness(level);
+}
+
+uint32_t getPanelBrightness() {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return 0;
+    }
+
+    int level = 0;
+    intf->getPanelBrightness(
+        [&](const auto &tmpError, const auto &tmpLevel) {
+            if (tmpError) {
+                return;
+            }
+
+            level = tmpLevel;
+        });
+
+    return level;
+}
+
+int minHdcpEncryptionLevelChanged(int dpy, uint32_t min_enc_level) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    return intf->minHdcpEncryptionLevelChanged(MapDisplayType(dpy), min_enc_level);
+}
+
+int refreshScreen() {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    return intf->refreshScreen();
+}
+
+int controlPartialUpdate(int dpy, bool enable) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    return intf->controlPartialUpdate(MapDisplayType(dpy), enable);
+}
+
+int toggleScreenUpdate(uint32_t on) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    return intf->toggleScreenUpdate(on == 1);
+}
+
+int setIdleTimeout(uint32_t value) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    return intf->setIdleTimeout(value);
+}
+
+int getHDRCapabilities(int dpy, DisplayHDRCapabilities *caps) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL || caps == NULL) {
+        return -1;
+    }
+
+    int error = -1;
+    intf->getHDRCapabilities(MapDisplayType(dpy),
+        [&](const auto &tmpError, const auto &tmpCaps) {
+            error = tmpError;
+            if (error) {
+                return;
+            }
+
+            caps->supported_hdr_types = tmpCaps.supportedHdrTypes;
+            caps->max_luminance = tmpCaps.maxLuminance;
+            caps->max_avg_luminance = tmpCaps.maxAvgLuminance;
+            caps->min_luminance = tmpCaps.minLuminance;
+        });
+
+    return error;
+}
+
+int setCameraLaunchStatus(uint32_t on) {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return -1;
+    }
+
+    return intf->setCameraLaunchStatus(on);
+}
+
+bool displayBWTransactionPending() {
+    android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+    if (intf == NULL) {
+        return 0;
+    }
+
+    int status = 0;
+    intf->displayBWTransactionPending(
+        [&](const auto &tmpError, const auto &tmpStatus) {
+            if (tmpError) {
+                return;
+            }
+
+            status = tmpStatus;
+        });
+
+    return status;
+}
+
+} // namespace display