summaryrefslogtreecommitdiff
authorbaocheng sun <baocheng.sun@amlogic.com>2020-05-28 09:48:49 (GMT)
committer baocheng sun <baocheng.sun@amlogic.com>2020-05-29 09:39:14 (GMT)
commit26d4b3ab2aa2310c0eb48ded1686c66cc9168553 (patch)
treeb3c825c7d732b7e59e43fb614afb2611797ec018
parentf34c749ec03c46df0271a0b30278e27906a13ef6 (diff)
downloadhwcomposer-26d4b3ab2aa2310c0eb48ded1686c66cc9168553.zip
hwcomposer-26d4b3ab2aa2310c0eb48ded1686c66cc9168553.tar.gz
hwcomposer-26d4b3ab2aa2310c0eb48ded1686c66cc9168553.tar.bz2
meson-display: add meson_display sdk on R [1/5]
PD#SWPL-14827 Problem: enable meson_display sdk on android Solution: Add a vendor hw binder service and implement a IPC api to handle display mode and screencap Verify: newton Change-Id: I8a36666e7e2ce85a4b81ca5c92283f9451d750f5 Signed-off-by: baocheng sun <baocheng.sun@amlogic.com>
Diffstat
-rw-r--r--mesondisplay/Android.bp86
-rw-r--r--mesondisplay/Android.mk271
-rw-r--r--mesondisplay/README.md15
-rw-r--r--mesondisplay/adapter/DisplayAdapterCommon.cpp42
-rw-r--r--mesondisplay/adapter/DisplayAdapterLocal.cpp153
-rw-r--r--mesondisplay/adapter/DisplayAdapterLocal.h35
-rw-r--r--mesondisplay/adapter/DisplayAdapterRecovery.cpp197
-rw-r--r--mesondisplay/adapter/DisplayAdapterRemote.cpp118
-rw-r--r--mesondisplay/adapter/DisplayAdapterRemote.h41
-rw-r--r--mesondisplay/adapter/DisplayClient.cpp125
-rw-r--r--mesondisplay/adapter/DisplayClient.h58
-rw-r--r--mesondisplay/include/DisplayAdapter.h94
-rw-r--r--mesondisplay/include/MesonLog.h64
-rw-r--r--mesondisplay/include/utile.h46
-rw-r--r--mesondisplay/service/Android.mk2
-rw-r--r--mesondisplay/service/DisplayService.cpp206
-rw-r--r--mesondisplay/service/DisplayService.h108
-rw-r--r--mesondisplay/service/current.txt1
-rw-r--r--mesondisplay/service/interfaces/Android.bp18
-rw-r--r--mesondisplay/service/interfaces/meson_display_ipc/1.0/Android.bp18
-rw-r--r--mesondisplay/service/interfaces/meson_display_ipc/1.0/IMesonDisplayIPC.hal38
-rw-r--r--mesondisplay/service/interfaces/meson_display_ipc/1.0/types.hal25
-rw-r--r--mesondisplay/test/Android.bp27
-rw-r--r--mesondisplay/test/display_client.cpp116
-rw-r--r--mesondisplay/test/display_recovery_test.cpp115
-rw-r--r--mesondisplay/test/display_screencap.cpp232
-rw-r--r--mesondisplay/test/ipc_test.cpp73
-rw-r--r--mesondisplay/test/test.sh19
28 files changed, 2343 insertions, 0 deletions
diff --git a/mesondisplay/Android.bp b/mesondisplay/Android.bp
new file mode 100644
index 0000000..0153800
--- a/dev/null
+++ b/mesondisplay/Android.bp
@@ -0,0 +1,86 @@
+// Copyright (C) 2008 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_static {
+ name: "libmeson_display_adapter_local_static",
+ vendor_available: true,
+ recovery_available: true,
+
+ cflags: [
+ "-DRECOVERY_MODE",
+ ],
+ srcs: [
+ "adapter/DisplayAdapterRecovery.cpp",
+ "adapter/DisplayAdapterCommon.cpp",
+ ],
+
+ local_include_dirs: [
+ "include",
+ "adapter",
+ ],
+
+ static_libs: [
+ "libjsoncpp",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libcutils",
+ ],
+
+ export_include_dirs: [
+ "include",
+ "adapter",
+ ],
+}
+
+cc_library_shared {
+ name: "libmeson_display_adapter_remote@1",
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ srcs: [
+ "adapter/DisplayAdapterRemote.cpp",
+ "adapter/DisplayAdapterCommon.cpp",
+ "adapter/DisplayClient.cpp",
+ ],
+
+ local_include_dirs: [
+ "include",
+ "adapter",
+ ],
+
+ shared_libs: [
+ "android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
+ "android.hardware.graphics.mapper@4.0",
+ "vendor.amlogic.display.meson_display_ipc@1.0",
+ "liblog",
+ "libcutils",
+ "libutils",
+ "libhidlbase",
+ ],
+
+ static_libs: [
+ "libjsoncpp",
+ ],
+
+ export_include_dirs: [
+ "include",
+ "adapter",
+ ],
+}
diff --git a/mesondisplay/Android.mk b/mesondisplay/Android.mk
new file mode 100644
index 0000000..e1e613e
--- a/dev/null
+++ b/mesondisplay/Android.mk
@@ -0,0 +1,271 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+
+HIDL_DEP_SHARED_LIBRARIES := \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ vendor.amlogic.display.meson_display_ipc@1.0 \
+ libui \
+ liblog \
+ libutils \
+ libcutils
+
+####################################################
+####### shared :libmeson_display_service ############
+####################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libmeson_display_service
+
+LOCAL_SRC_FILES := \
+ service/DisplayService.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/include \
+ $(LOCAL_PATH)/service
+
+LOCAL_SHARED_LIBRARIES := \
+ libamgralloc_ext \
+ $(HIDL_DEP_SHARED_LIBRARIES)
+
+LOCAL_STATIC_LIBRARIES += \
+ libmeson_display_adapter_common \
+ hwc.utils_static \
+ libjsoncpp
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_C_INCLUDES)
+
+LOCAL_EXPORT_STATIC_LIBRARY_HEADERS := \
+ $(LOCAL_STATIC_LIBRARIES)
+
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+ $(LOCAL_SHARED_LIBRARIES)
+
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 28 && echo OK),OK)
+LOCAL_PROPRIETARY_MODULE := true
+endif
+include $(BUILD_SHARED_LIBRARY)
+
+###########################################################
+####### shared :libmeson_display_adapter_common ##########
+###########################################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := libmeson_display_adapter_common
+LOCAL_CFLAGS :=
+
+LOCAL_SRC_FILES := \
+ adapter/DisplayAdapterCommon.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/adapter \
+ $(LOCAL_PATH)/include
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_C_INCLUDES)
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libcutils
+
+LOCAL_WHOLE_STATIC_LIBRARIES := \
+ libjsoncpp
+
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 28 && echo OK),OK)
+LOCAL_PROPRIETARY_MODULE := true
+endif
+include $(BUILD_STATIC_LIBRARY)
+
+###########################################################
+####### static :libmeson_display_adapter_local ############
+###########################################################
+include $(CLEAR_VARS)
+# need distinct with static lib "libmeson_display_adapter_local" for recovery on Android.bp
+LOCAL_MODULE := libmeson_display_adapter_local
+LOCAL_CFLAGS :=
+
+LOCAL_SRC_FILES := \
+ adapter/DisplayAdapterLocal.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/include \
+ $(LOCAL_PATH)/adapter
+
+#copy frme hwc. because hwc.display_static depend it.
+LOCAL_HWC_SHARED_LIBS := \
+ libamgralloc_ext \
+ libcutils \
+ liblog \
+ libdl \
+ libhardware \
+ libutils \
+ libsync \
+ libion \
+ libge2d \
+ libui \
+ vendor.amlogic.hardware.systemcontrol@1.0 \
+ vendor.amlogic.hardware.systemcontrol@1.1 \
+ libbase \
+ libhidlbase \
+ libbinder \
+ libhidltransport
+
+LOCAL_SHARED_LIBRARIES := \
+ $(LOCAL_HWC_SHARED_LIBS) \
+ liblog
+
+LOCAL_STATIC_LIBRARIES += \
+ libmeson_display_adapter_common \
+ hwc.common_static \
+ hwc.composition_static \
+ hwc.postprocessor_static \
+ hwc.display_static \
+ hwc.utils_static \
+ hwc.base_static \
+ hwc.debug_static \
+ hwc.composer_static \
+ libomxutil
+
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+ $(LOCAL_SHARED_LIBRARIES)
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_C_INCLUDES)
+
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 28 && echo OK),OK)
+LOCAL_PROPRIETARY_MODULE := true
+endif
+include $(BUILD_STATIC_LIBRARY)
+
+####################################################
+####### shared :libmeson_display_adapter_remote ####
+####################################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libmeson_display_adapter_remote
+
+LOCAL_SRC_FILES:= \
+ adapter/DisplayAdapterRemote.cpp \
+ adapter/DisplayClient.cpp
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include \
+ $(LOCAL_PATH)/adapter
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+ $(LOCAL_PATH)/include
+
+LOCAL_SHARED_LIBRARIES := \
+ $(HIDL_DEP_SHARED_LIBRARIES) \
+ android.hardware.graphics.mapper@2.0 \
+ android.hardware.graphics.mapper@3.0 \
+ android.hardware.graphics.mapper@4.0
+
+LOCAL_STATIC_LIBRARIES := \
+ libmeson_display_adapter_common \
+ libjsoncpp
+
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+ $(LOCAL_SHARED_LIBRARIES)
+
+LOCAL_EXPORT_STATIC_LIBRARY_HEADERS := \
+ $(LOCAL_STATIC_LIBRARIES)
+
+LOCAL_MODULE_TAGS := optional
+
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
+LOCAL_PROPRIETARY_MODULE := true
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
+#######################################
+####### exec :meson_display_client ####
+#######################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= meson_display_client
+
+LOCAL_SRC_FILES:= \
+ test/display_client.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libmeson_display_adapter_remote
+
+
+LOCAL_MODULE_TAGS := optional
+
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
+LOCAL_PROPRIETARY_MODULE := true
+endif
+
+include $(BUILD_EXECUTABLE)
+
+
+####################################
+####### exec :test_ipc ##########
+####################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= test_ipc
+
+LOCAL_SRC_FILES := \
+ test/ipc_test.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ $(HIDL_DEP_SHARED_LIBRARIES) \
+ libmeson_display_adapter_remote \
+ libmeson_display_service
+
+LOCAL_STATIC_LIBRARIES := \
+ libmeson_display_adapter_common \
+ libjsoncpp
+
+LOCAL_MODULE_TAGS := optional
+
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
+LOCAL_PROPRIETARY_MODULE := true
+endif
+include $(BUILD_EXECUTABLE)
+
+
+#######################################
+####### exec :test_display_recovery ####
+#######################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= test_display_recovery
+
+LOCAL_CFLAGS += -DRECOVERY_MODE
+
+LOCAL_SRC_FILES := \
+ test/display_recovery_test.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ $(HIDL_DEP_SHARED_LIBRARIES)
+
+LOCAL_STATIC_LIBRARIES := \
+ libmeson_display_adapter_local_static
+
+LOCAL_MODULE_TAGS := optional
+
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
+LOCAL_PROPRIETARY_MODULE := true
+endif
+include $(BUILD_EXECUTABLE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/mesondisplay/README.md b/mesondisplay/README.md
new file mode 100644
index 0000000..3f58f68
--- a/dev/null
+++ b/mesondisplay/README.md
@@ -0,0 +1,15 @@
+# introduc
+the hwc used api implement on display_adapter_local, systemcontrol and other process use a
+display client which under display_adapter_remote
+architecture like below:
+## Android mode:
+ HWC--->DisplayServer--->DisplayAdapterLocal(shared library)
+ ||
+ ||(HDIL Binder)
+ ||
+ DisplayClient <-----|
+systemcontrol--> DisplayAdapterRemot-->|
+
+## Android Recovery mode:
+systemcontrol--> DisplayAdapterLocal(static library).
+
diff --git a/mesondisplay/adapter/DisplayAdapterCommon.cpp b/mesondisplay/adapter/DisplayAdapterCommon.cpp
new file mode 100644
index 0000000..45c9bae
--- a/dev/null
+++ b/mesondisplay/adapter/DisplayAdapterCommon.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#include "DisplayAdapter.h"
+#include <json/json.h>
+namespace meson{
+
+bool Json2DisplayMode(const Json::Value& json, DisplayModeInfo& mode) {
+ if (json.isMember("name") && json.isMember("dpiX") &&
+ json.isMember("dpiY") && json.isMember("pixelW") &&
+ json.isMember("pixelH") && json.isMember("refreshRate")) {
+ if (!json["name"].isString()) {
+ return false;
+ }
+ mode.name = json["name"].asString();
+ mode.dpiX = json["dpiX"].asUInt();
+ mode.dpiY = json["dpiY"].asUInt();
+ mode.pixelW = json["pixelW"].asUInt();
+ mode.pixelH = json["pixelH"].asUInt();
+ mode.refreshRate = json["refreshRate"].asFloat();
+ return true;
+ }
+ return false;
+};
+
+bool DisplayMode2Json(const DisplayModeInfo& mode, Json::Value& json) {
+ json["name"] = mode.name;
+ json["dpiX"] = mode.dpiX;
+ json["dpiY"] = mode.dpiY;
+ json["pixelW"] = mode.pixelW;
+ json["pixelH"] = mode.pixelH;
+ json["refreshRate"] = mode.refreshRate;
+ return true;
+};
+
+}; //namespace meson
diff --git a/mesondisplay/adapter/DisplayAdapterLocal.cpp b/mesondisplay/adapter/DisplayAdapterLocal.cpp
new file mode 100644
index 0000000..9485c90
--- a/dev/null
+++ b/mesondisplay/adapter/DisplayAdapterLocal.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#include "HwDisplayManager.h"
+#include "HwDisplayConnector.h"
+#include "HwDisplayCrtc.h"
+#include "DisplayAdapterLocal.h"
+
+#include "misc.h"
+#include "MesonHwc2.h"
+#include "HwcConfig.h"
+#include "MesonLog.h"
+
+namespace meson{
+
+using namespace std;
+using ConnectorType = DisplayAdapter::ConnectorType;
+using BackendType = DisplayAdapter::BackendType;
+
+void DisplayTypeConv(drm_connector_type_t& type, ConnectorType displayType) {
+ switch (displayType) {
+ case DisplayAdapter::CONN_TYPE_HDMI:
+ type = DRM_MODE_CONNECTOR_HDMI;
+ break;
+ case DisplayAdapter::CONN_TYPE_PANEL:
+ type = DRM_MODE_CONNECTOR_PANEL;
+ break;
+ case DisplayAdapter::CONN_TYPE_DUMMY:
+ type = DRM_MODE_CONNECTOR_DUMMY;
+ break;
+ }
+}
+
+void DisplayModeConv(DisplayModeInfo& mode, drm_mode_info_t& mode_in) {
+ mode.name = mode_in.name;
+ mode.dpiX = mode_in.dpiX;
+ mode.dpiY = mode_in.dpiY;
+ mode.pixelW = mode_in.pixelW;
+ mode.pixelH = mode_in.pixelH;
+ mode.refreshRate = mode_in.refreshRate;
+}
+
+
+DisplayAdapterLocal::DisplayAdapterLocal() {
+}
+
+DisplayAdapter::BackendType DisplayAdapterLocal::displayType() {
+ return DISPLAY_TYPE_FBDEV;
+}
+
+bool DisplayAdapterLocal::getSupportDisplayModes(vector<DisplayModeInfo>& displayModeList, ConnectorType displayType) {
+ drm_connector_type_t type;
+ std::shared_ptr<HwDisplayConnector> connector;
+ map<uint32_t, drm_mode_info_t> modes;
+ DisplayTypeConv(type, displayType);
+ HwDisplayManager::getInstance().getConnector(connector, type);
+ if (connector) {
+ connector->getModes(modes);
+ displayModeList.clear();
+ DisplayModeInfo mode;
+ for (auto it : modes) {
+ DisplayModeConv(mode, it.second);
+ displayModeList.push_back(mode);
+ }
+ }
+ return true;;
+};
+
+bool DisplayAdapterLocal::getDisplayMode(string& mode, ConnectorType displayType) {
+ drm_connector_type_t type;
+ std::shared_ptr<HwDisplayConnector> connector;
+ drm_mode_info_t mode_in;
+
+ DisplayTypeConv(type, displayType);
+ HwDisplayManager::getInstance().getConnector(connector, type);
+ if (connector && connector->mCrtc) {
+ connector->mCrtc->getMode(mode_in);
+ mode = mode_in.name;
+ }
+ DEBUG_INFO("GetDisplayMode:%s", mode.c_str());
+ return true;
+}
+
+bool DisplayAdapterLocal::setDisplayMode(const string& mode, ConnectorType displayType) {
+ drm_connector_type_t type;
+ std::shared_ptr<HwDisplayConnector> connector;
+ drm_mode_info_t mock;
+ strncpy(mock.name, mode.c_str(), DRM_DISPLAY_MODE_LEN);
+ DisplayTypeConv(type, displayType);
+
+ DEBUG_INFO("SetDisplay[%s] Mode to \"%s\"", type == DRM_MODE_CONNECTOR_HDMI ? "HDMI" :
+ (type == DRM_MODE_CONNECTOR_PANEL ? "panel":"dummy"), mode.c_str());
+
+ HwDisplayManager::getInstance().getConnector(connector, type);
+ if (connector && connector->mCrtc) {
+ connector->mCrtc->setMode(mock);
+ }
+ DEBUG_INFO("SetDisplayMode done");
+ return true;
+};
+
+bool DisplayAdapterLocal::captureDisplayScreen(const native_handle_t **outBufferHandle) {
+ // get framebuffer width and height
+ uint32_t fbW = 1290;
+ uint32_t fbH = 1080;
+ HwcConfig::getFramebufferSize(0, fbW, fbH);
+
+ if (sys_get_bool_prop("vendor.hwc.3dmode", false)) {
+ fbW = 960;
+ fbH = 540;
+ }
+
+ // format is always HAL_PIXEL_FORMAT_RGB_888
+ native_handle_t* hnd = gralloc_alloc_dma_buf(fbW, fbH, HAL_PIXEL_FORMAT_RGB_888, true, false);
+ if (hnd == nullptr || am_gralloc_get_buffer_fd(hnd) < 0) {
+ MESON_LOGE("DisplayAdapterLocal::captureDisplayScreen alloc buffer error");
+ return false;
+ }
+
+ int32_t ret = MesonHwc2::getInstance().captureDisplayScreen(hnd);
+ *outBufferHandle = hnd;
+
+ if (ret != 1) {
+ gralloc_unref_dma_buf(hnd);
+ gralloc_free_dma_buf(hnd);
+ }
+
+ return ret == 1 ? true : false;
+}
+
+std::unique_ptr<DisplayAdapter> DisplayAdapterLocal::create(DisplayAdapter::BackendType type) {
+ switch (type) {
+ case BackendType::DISPLAY_TYPE_DRM:
+ return {nullptr};
+ case BackendType::DISPLAY_TYPE_FBDEV:
+ return static_cast<std::unique_ptr<DisplayAdapter>>(std::make_unique<DisplayAdapterLocal>());
+ default:
+ return static_cast<std::unique_ptr<DisplayAdapter>>(std::make_unique<DisplayAdapterLocal>());
+ }
+}
+
+std::unique_ptr<DisplayAdapter> DisplayAdapterCreateLocal(DisplayAdapter::BackendType type) {
+ return DisplayAdapterLocal::create(type);
+};
+
+
+}; //namespace meson
diff --git a/mesondisplay/adapter/DisplayAdapterLocal.h b/mesondisplay/adapter/DisplayAdapterLocal.h
new file mode 100644
index 0000000..6460749
--- a/dev/null
+++ b/mesondisplay/adapter/DisplayAdapterLocal.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#pragma once
+#include "DisplayAdapter.h"
+#include "utile.h"
+
+namespace meson{
+
+class DisplayAdapterLocal: public DisplayAdapter {
+public:
+ AdapterType type() override { return ADAPTER_TYPE_LOCAL; }
+ BackendType displayType() override;
+
+ bool getSupportDisplayModes(vector<DisplayModeInfo>& displayModeList, ConnectorType displayType) override;
+ bool getDisplayMode(string& mode, ConnectorType displayType) override;
+ bool setDisplayMode(const string& mode, ConnectorType displayType) override;
+ //bool setPrefDisplayMode(const string& mode, ConnectorType displayType) override;
+ bool captureDisplayScreen(const native_handle_t **outBufferHandle) override;
+ static std::unique_ptr<DisplayAdapter> create(DisplayAdapter::BackendType type);
+
+ DisplayAdapterLocal();
+ ~DisplayAdapterLocal() = default;
+private:
+
+ DISALLOW_COPY_AND_ASSIGN(DisplayAdapterLocal);
+};
+
+}; //namespace meson
diff --git a/mesondisplay/adapter/DisplayAdapterRecovery.cpp b/mesondisplay/adapter/DisplayAdapterRecovery.cpp
new file mode 100644
index 0000000..1776c74
--- a/dev/null
+++ b/mesondisplay/adapter/DisplayAdapterRecovery.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "utile.h"
+#include <unistd.h>
+#include "DisplayAdapterLocal.h"
+#include <fcntl.h>
+namespace meson{
+//For recovery mode for temporary.
+#define SYSFS_DISPLAY_MODE "/sys/class/display/mode"
+#define SYSFS_DISPLAY_MODE2 "/sys/class/display2/mode"
+#define MAX_BUFFER_LEN_EDID 4096
+#define READ_BUFFER_LEN 64
+#define FORMAT_DISPLAY_HDMI_EDID "/sys/class/amhdmitx/amhdmitx0/disp_cap"//RX support display mode
+
+#define FS_READ(path, buffer, len) \
+do { \
+ int fd;\
+ if ((fd = open(path, O_RDONLY)) < 0) { \
+ perror(path);\
+ DEBUG_INFO("open file %s error!", path);\
+ goto error_handle; \
+ } \
+ if (read(fd, buffer, len) == -1) { \
+ perror(path); \
+ DEBUG_INFO("Read file %s error!", path); \
+ close(fd); \
+ goto error_handle; \
+ } \
+ close(fd); \
+} while (0)
+
+#define FS_WRITE(path, buffer, len) \
+do { \
+ int fd;\
+ if ((fd = open(path, O_RDWR)) < 0) { \
+ perror(path);\
+ DEBUG_INFO("open file %s error!", path);\
+ goto error_handle; \
+ } \
+ if (write(fd, buffer, len) == -1) { \
+ perror(path); \
+ DEBUG_INFO("Read file %s error!", path); \
+ close(fd); \
+ goto error_handle; \
+ } \
+ close(fd); \
+} while (0)
+
+
+
+#define CONNECT_HDMI_INDEX CONN1;
+#define CONNECT_PANEL_INDEX CONN2;
+#define CONNECT_DUMMY_INDEX CONN3;
+
+using namespace std;
+using ConnectorType = DisplayAdapter::ConnectorType;
+typedef enum {
+ CONN1 = 0,
+ CONN2 = 1,
+ CONN3 = 2,
+} connector_index;
+
+void DisplayTypeConvToIndex(ConnectorType displayType, connector_index& type) {
+ switch (displayType) {
+ case DisplayAdapter::CONN_TYPE_HDMI:
+ type = CONNECT_HDMI_INDEX;
+ break;
+ case DisplayAdapter::CONN_TYPE_PANEL:
+ type = CONNECT_PANEL_INDEX;
+ break;
+ case DisplayAdapter::CONN_TYPE_DUMMY:
+ type = CONNECT_DUMMY_INDEX;
+ break;
+ }
+}
+
+DisplayAdapterLocal::DisplayAdapterLocal() {
+}
+
+DisplayAdapter::BackendType DisplayAdapterLocal::displayType() {
+ return DISPLAY_TYPE_FBDEV;
+}
+
+bool GetHDMIEDID(char* buffer, int len) {
+ FS_READ(FORMAT_DISPLAY_HDMI_EDID, buffer, len);
+ return true;
+error_handle:
+ DEBUG_INFO("Get EDID error:%s", strerror(errno));
+ return false;
+}
+
+bool DisplayAdapterLocal::getSupportDisplayModes(vector<DisplayModeInfo>& displayModeList, ConnectorType displayType) {
+ DisplayModeInfo mode;
+ if (displayType == DisplayAdapter::CONN_TYPE_HDMI) {
+ displayModeList.clear();
+ char edid_buf[MAX_BUFFER_LEN_EDID];
+ const char *delim = "\n";
+ char *ptr = NULL;
+ if (false == GetHDMIEDID(edid_buf, MAX_BUFFER_LEN_EDID)) {
+ return false;
+ }
+ ptr = strtok(edid_buf, delim);
+ while (ptr != NULL) {
+ int len = strlen(ptr);
+ if (ptr[len - 1] == '*')
+ ptr[len - 1] = '\0';
+
+ mode.name = ptr;
+ //TODO: Add other info
+ displayModeList.push_back(mode);
+ ptr = strtok(NULL, delim);
+ };
+ } else {
+ //TODO: now just show the current mode beside HDMI
+ displayModeList.clear();
+ getDisplayMode(mode.name, displayType);
+ displayModeList.push_back(mode);
+ }
+
+ return true;
+};
+
+bool DisplayAdapterLocal::getDisplayMode(string& mode, ConnectorType displayType) {
+ connector_index conn;
+ char buf[READ_BUFFER_LEN] = {0};
+ const char* path = NULL;
+
+ DisplayTypeConvToIndex(displayType, conn);
+ if (conn == CONN1) {
+ path = SYSFS_DISPLAY_MODE;
+ } else if (conn == CONN2) {
+ path = SYSFS_DISPLAY_MODE2;
+ } else {
+ DEBUG_INFO("No such device");
+ assert(0);
+ return false;
+ }
+
+ FS_READ(path, buf, READ_BUFFER_LEN);
+ mode = buf;
+ return true;
+error_handle:
+ return false;
+}
+
+bool DisplayAdapterLocal::setDisplayMode(const string& mode, ConnectorType displayType) {
+ connector_index conn ;
+ DisplayTypeConvToIndex(displayType, conn);
+ const char* path = NULL;
+
+ if (conn == CONN1) {
+ path = SYSFS_DISPLAY_MODE;
+ } else if (conn == CONN2) {
+ path = SYSFS_DISPLAY_MODE2;
+ } else {
+ DEBUG_INFO("No such device");
+ assert(0);
+ return false;
+ }
+
+ FS_WRITE(path, mode.c_str(), mode.length());
+
+ return true;
+error_handle:
+ return false;
+};
+
+bool DisplayAdapterLocal::captureDisplayScreen(const native_handle_t **outBufferHandle) {
+ *outBufferHandle = nullptr;
+ return true;
+}
+
+std::unique_ptr<DisplayAdapter> DisplayAdapterLocal::create(DisplayAdapter::BackendType type) {
+ switch (type) {
+ case BackendType::DISPLAY_TYPE_DRM:
+ return {nullptr};
+ case BackendType::DISPLAY_TYPE_FBDEV:
+ return static_cast<std::unique_ptr<DisplayAdapter>>(std::make_unique<DisplayAdapterLocal>());
+ default:
+ return static_cast<std::unique_ptr<DisplayAdapter>>(std::make_unique<DisplayAdapterLocal>());
+ }
+}
+
+std::unique_ptr<DisplayAdapter> DisplayAdapterCreateLocal(DisplayAdapter::BackendType type) {
+ return DisplayAdapterLocal::create(type);
+};
+
+}; //namespace meson
diff --git a/mesondisplay/adapter/DisplayAdapterRemote.cpp b/mesondisplay/adapter/DisplayAdapterRemote.cpp
new file mode 100644
index 0000000..64df199
--- a/dev/null
+++ b/mesondisplay/adapter/DisplayAdapterRemote.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#include "DisplayAdapter.h"
+#include "DisplayClient.h"
+#include "DisplayAdapterRemote.h"
+
+#define IF_SERVER_NOT_READY_RETURN(ret) \
+ if (!connectServerIfNeed()) { \
+ DEBUG_INFO("Can't connect with server!"); \
+ return ret; \
+ }
+
+namespace meson{
+using namespace std;
+using ConnectorType = DisplayAdapter::ConnectorType;
+using BackendType = DisplayAdapter::BackendType;
+
+DisplayAdapter::BackendType DisplayAdapterRemote::displayType() {
+ Json::Value cmd, ret;
+ IF_SERVER_NOT_READY_RETURN(DisplayAdapter::DISPLAY_TYPE_MAX);
+ cmd["cmd"] = "displayType";
+ ipc->send_request_wait_reply(cmd, ret);
+ if (ret.isMember("ret")) {
+ DEBUG_INFO("Server reply error!");
+ return (DisplayAdapter::BackendType)ret["ret"].asUInt();
+ } else {
+ return DisplayAdapter::DISPLAY_TYPE_MAX;
+ }
+};
+
+bool DisplayAdapterRemote::getSupportDisplayModes(vector<DisplayModeInfo>& displayModeList, ConnectorType displayType) {
+ Json::Value cmd, ret;
+ Json::FastWriter write;
+ IF_SERVER_NOT_READY_RETURN(false);
+ cmd["cmd"] = "getSupportDisplayModes";
+ cmd["p_displayType"] = displayType;
+ ipc->send_request_wait_reply(cmd, ret);
+ if (ret.isMember("ret") && ret["ret"].isMember("displayModeList")) {
+ Json::Value& list = ret["ret"]["displayModeList"];
+ displayModeList.clear();
+ for (unsigned int i = 0; i < list.size(); i++) {
+ Json::Value& mode_in = list[i];
+ DisplayModeInfo mode;
+ if (true == Json2DisplayMode(mode_in, mode)) {
+ displayModeList.push_back(mode);
+ } else {
+ DEBUG_INFO("Get Wrong DisplayMode info");
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+};
+bool DisplayAdapterRemote::getDisplayMode(string& mode, ConnectorType displayType) {
+ Json::Value cmd, ret;
+ Json::FastWriter write;
+ IF_SERVER_NOT_READY_RETURN(false);
+ cmd["cmd"] = "getDisplayMode";
+ cmd["p_displayType"] = displayType;
+ ipc->send_request_wait_reply(cmd, ret);
+ if (ret.isMember("ret") && ret["ret"]["mode"].isString()) {
+ mode = ret["ret"]["mode"].asString();
+ return true;
+ } else
+ return false;
+};
+bool DisplayAdapterRemote::setDisplayMode(const string& mode, ConnectorType displayType) {
+ Json::Value cmd;
+ IF_SERVER_NOT_READY_RETURN(false);
+ cmd["cmd"] = "setDisplayMode";
+ cmd["p_mode"] = mode;
+ cmd["p_displayType"] = displayType;
+ ipc->send_request(cmd);
+ return true;
+};
+bool DisplayAdapterRemote::setPrefDisplayMode(const string& mode, ConnectorType displayType) {
+ Json::Value cmd;
+ IF_SERVER_NOT_READY_RETURN(false);
+ cmd["cmd"] = "setPrefDisplayMode";
+ cmd["p_mode"] = mode;
+ cmd["p_displayType"] = displayType;
+ ipc->send_request(cmd);
+ return true;
+};
+
+bool DisplayAdapterRemote::captureDisplayScreen(const native_handle_t **outBufferHandle) {
+ IF_SERVER_NOT_READY_RETURN(false);
+ return ipc->captureDisplayScreen(outBufferHandle);
+}
+
+DisplayAdapterRemote::DisplayAdapterRemote() {
+ ipc = DisplayClient::create("DisplayAdapterRemote");
+ if (!ipc)
+ DEBUG_INFO("Error when connect with Server");
+}
+
+std::unique_ptr<DisplayAdapter> DisplayAdapterRemote::create() {
+ return static_cast<std::unique_ptr<DisplayAdapter>>(std::make_unique<DisplayAdapterRemote>());
+}
+
+bool DisplayAdapterRemote::connectServerIfNeed() {
+ return ipc->tryGetService();
+};
+
+std::unique_ptr<DisplayAdapter> DisplayAdapterCreateRemote() {
+ return DisplayAdapterRemote::create();
+};
+
+} //namespace android
diff --git a/mesondisplay/adapter/DisplayAdapterRemote.h b/mesondisplay/adapter/DisplayAdapterRemote.h
new file mode 100644
index 0000000..89c9f42
--- a/dev/null
+++ b/mesondisplay/adapter/DisplayAdapterRemote.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#pragma once
+#include <stdbool.h>
+#include "utile.h"
+#include "DisplayAdapter.h"
+#include "DisplayClient.h"
+
+namespace meson{
+using namespace std;
+
+class DisplayAdapterRemote: public DisplayAdapter {
+public:
+ AdapterType type() override { return ADAPTER_TYPE_REMOTE; }
+ BackendType displayType() override;
+
+ bool getSupportDisplayModes(vector<DisplayModeInfo>& displayModeList, ConnectorType displayType) override;
+ bool getDisplayMode(string& mode, ConnectorType displayType) override;
+ bool setDisplayMode(const string& mode, ConnectorType displayType) override;
+ bool setPrefDisplayMode(const string& mode, ConnectorType displayType) override;
+ bool captureDisplayScreen(const native_handle_t **outBufferHandle) override;
+
+ static std::unique_ptr<DisplayAdapter> create();
+ DisplayAdapterRemote();
+ ~DisplayAdapterRemote() = default;
+private:
+
+ // For later start server.
+ bool connectServerIfNeed();
+ std::unique_ptr<DisplayClient> ipc;
+ DISALLOW_COPY_AND_ASSIGN(DisplayAdapterRemote);
+};
+
+} //namespace android
diff --git a/mesondisplay/adapter/DisplayClient.cpp b/mesondisplay/adapter/DisplayClient.cpp
new file mode 100644
index 0000000..51a6fce
--- a/dev/null
+++ b/mesondisplay/adapter/DisplayClient.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2020 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#include "DisplayClient.h"
+#include "MesonLog.h"
+
+namespace meson{
+using namespace std;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::graphics::mapper::V3_0::IMapper;
+using ::vendor::amlogic::display::meson_display_ipc::V1_0::IMesonDisplayIPC;
+using ::vendor::amlogic::display::meson_display_ipc::V1_0::Error;
+
+static const int MAX_GET_SERVICE_COUNT = 5;
+
+DisplayClient::DisplayClient(std::string str)
+ : name(str) {
+ meson_ipc_client = NULL;
+ is_ready = false;
+ //Note: you need call tryGetService befor other api called.
+ //tryGetService();
+}
+
+bool DisplayClient::tryGetService() {
+ if (is_ready == true)
+ return true;
+
+ int count = 0;
+ while (meson_ipc_client == NULL && count <= MAX_GET_SERVICE_COUNT) {
+ DEBUG_INFO("Try get meson_ipc service(%d)", count);
+ meson_ipc_client = IMesonDisplayIPC::tryGetService();
+ count++;
+ }
+
+ mMapper = IMapper::getService();
+
+ if (meson_ipc_client && mMapper)
+ is_ready = true;
+ else
+ is_ready = false;
+
+ return is_ready;
+}
+
+std::unique_ptr<DisplayClient> DisplayClient::create(std::string name) {
+ return std::unique_ptr<DisplayClient>(new DisplayClient(name));
+}
+
+int32_t DisplayClient::send_request_wait_reply(Json::Value& data, Json::Value& out) {
+ Json::FastWriter write;
+ bool ret = false;
+ const hidl_string str = write.write(data);
+ if (is_ready) {
+ DEBUG_INFO("Client SendSync :%s", str.c_str());
+ meson_ipc_client->send_msg_wait_reply(str, [&out, &ret](const hidl_string& in) {
+ Json::Reader reader;
+ const std::string tmp = in.c_str();
+ ret = reader.parse(tmp, out);
+ });
+ }
+ if (ret == false) {
+ DEBUG_INFO("Server reply format error !");
+ }
+ return 0;
+}
+
+int32_t DisplayClient::send_request(Json::Value& data) {
+ Json::FastWriter write;
+ const hidl_string str = write.write(data);
+ if (is_ready) {
+ DEBUG_INFO("Client Send :%s", str.c_str());
+ meson_ipc_client->send_msg(str);
+ }
+ return 0;
+}
+
+bool DisplayClient::captureDisplayScreen(const native_handle_t** outBufferHandle) {
+ MESON_LOGD("Client captureDisplayScreen");
+ if (!is_ready) {
+ MESON_LOGE("captureDisplayScreen Server not ready");
+ return false;
+ }
+
+ Error error;
+ hidl_vec<hidl_handle> dataHandles;
+ const native_handle_t *bufferHandle = nullptr;
+
+ meson_ipc_client->captureDisplayScreen(0 /*displayId reserved*/, 0 /*layerId reserved*/,
+ [&] (const auto& tmpError, const auto& tmpOutHandles){
+ error = tmpError;
+ dataHandles.setToExternal(const_cast<hidl_handle*>(tmpOutHandles.data()),
+ tmpOutHandles.size());
+ });
+ if (error != Error::NONE) {
+ MESON_LOGE("captureDislayScreen failed");
+ return false;
+ }
+
+ // only import the first buffer handle.
+ // We assumed there is only one native handle currently
+ if (dataHandles.size() > 0) {
+ mMapper->importBuffer(dataHandles[0],
+ [&](const auto& tmpError, const auto& tmpBufferHandle) {
+ if (tmpError != android::hardware::graphics::mapper::V3_0::Error::NONE) {
+ MESON_LOGE("captureDisplayScreen mapper import buffer error:%d", tmpError);
+ return;
+ }
+ bufferHandle = static_cast<const native_handle_t*>(tmpBufferHandle);
+ });
+ }
+
+ *outBufferHandle = bufferHandle;
+
+ return true;
+}
+
+} // meson
diff --git a/mesondisplay/adapter/DisplayClient.h b/mesondisplay/adapter/DisplayClient.h
new file mode 100644
index 0000000..8eb91af
--- a/dev/null
+++ b/mesondisplay/adapter/DisplayClient.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2020 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#pragma once
+
+#include <json/json.h>
+#include <stdbool.h>
+#include <string>
+
+#include <utils/StrongPointer.h>
+#include <cutils/native_handle.h>
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#include <vendor/amlogic/display/meson_display_ipc/1.0/IMesonDisplayIPC.h>
+
+#include "utile.h"
+
+namespace meson {
+using namespace std;
+using ::android::sp;
+using ::vendor::amlogic::display::meson_display_ipc::V1_0::IMesonDisplayIPC;
+//using ::android::hardware::graphics::mapper;
+using ::android::hardware::graphics::mapper::V3_0::IMapper;
+
+class DisplayClient {
+public:
+ DisplayClient(std::string name);
+ ~DisplayClient() = default;
+ bool tryGetService();
+ int32_t send_request_wait_reply(Json::Value& data, Json::Value& out);
+ int32_t send_request(Json::Value& data);
+ static std::unique_ptr<DisplayClient> create(std::string name);
+ bool captureDisplayScreen(const native_handle_t** outBufferHandle);
+
+protected:
+ std::string name;
+ sp<IMesonDisplayIPC> meson_ipc_client;
+ //sp<android::hardware::graphics::mapper::V2_0::IMapper> mMapper;
+// sp<mapper::V2_0::IMapper> mMapper2;
+// sp<mapper::V3_0::IMapper> mMapper3;
+// sp<mapper::V4_0::IMapper> mMapper4;
+ sp<IMapper> mMapper;
+
+ //std::unique_ptr<GrallocMapper> mMapper;
+ bool is_ready;
+private:
+ DISALLOW_COPY_AND_ASSIGN(DisplayClient);
+};
+
+} //namespace meson
diff --git a/mesondisplay/include/DisplayAdapter.h b/mesondisplay/include/DisplayAdapter.h
new file mode 100644
index 0000000..13c5b6c
--- a/dev/null
+++ b/mesondisplay/include/DisplayAdapter.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+#pragma once
+#include <stdbool.h>
+#include <string>
+#include <memory>
+#include <vector>
+#include <cutils/native_handle.h>
+#include "utile.h"
+
+namespace Json {
+ class Value;
+}
+
+namespace meson{
+using namespace std;
+
+typedef struct {
+ string name;
+ uint32_t dpiX, dpiY;
+ uint32_t pixelW, pixelH;
+ float refreshRate;
+} DisplayModeInfo;
+
+
+class DisplayAdapter {
+public:
+ typedef enum {
+ ADAPTER_TYPE_REMOTE = 0,
+ ADAPTER_TYPE_LOCAL = 1,
+ } AdapterType;
+ typedef enum {
+ DISPLAY_TYPE_DRM = 0,
+ DISPLAY_TYPE_FBDEV = 1,
+ DISPLAY_TYPE_MAX,
+ } BackendType;
+ typedef enum {
+ CONN_TYPE_DUMMY = 0,
+ CONN_TYPE_HDMI = 1,
+ CONN_TYPE_PANEL = 2,
+ } ConnectorType;
+ virtual AdapterType type() = 0;
+ virtual BackendType displayType() = 0;
+ virtual bool getSupportDisplayModes(vector<DisplayModeInfo>& displayModeList, ConnectorType displayType) {
+ UNUSED(displayModeList);
+ UNUSED(displayType);
+ NOTIMPLEMENTED;
+ return false;
+ };
+ virtual bool getDisplayMode(string& mode, ConnectorType displayType) {
+ UNUSED(mode);
+ UNUSED(displayType);
+ NOTIMPLEMENTED;
+ return false;
+ };
+ virtual bool setDisplayMode(const string& mode, ConnectorType displayType) {
+ UNUSED(mode);
+ UNUSED(displayType);
+ NOTIMPLEMENTED;
+ return false;
+ };
+ virtual bool setPrefDisplayMode(const string& mode, ConnectorType displayType) {
+ UNUSED(mode);
+ UNUSED(displayType);
+ NOTIMPLEMENTED;
+ return false;
+ };
+
+ virtual bool captureDisplayScreen(const native_handle_t **outBufferHandle) = 0;
+
+ virtual ~DisplayAdapter() = default;
+ DisplayAdapter() = default;
+private:
+ DisplayAdapter(const DisplayAdapter&) = delete;
+ void operator=(const DisplayAdapter&) = delete;
+};
+
+
+bool Json2DisplayMode(const Json::Value& json, DisplayModeInfo& mode);
+
+bool DisplayMode2Json(const DisplayModeInfo& mode, Json::Value& json);
+
+std::unique_ptr<DisplayAdapter> DisplayAdapterCreateLocal(DisplayAdapter::BackendType type);
+std::unique_ptr<DisplayAdapter> DisplayAdapterCreateRemote();
+
+
+};
+
diff --git a/mesondisplay/include/MesonLog.h b/mesondisplay/include/MesonLog.h
new file mode 100644
index 0000000..212a39a
--- a/dev/null
+++ b/mesondisplay/include/MesonLog.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#ifndef MESON_LOG_H
+#define MESON_LOG_H
+
+#ifndef LOG_TAG
+#define LOG_TAG "MesonDisplay"
+#endif
+
+#define LOG_NDEBUG 0
+#include <log/log.h>
+#include <stdlib.h>
+
+#ifdef HWC_RELEASE
+#define MESON_DEBUG_LEVEL 0
+#else
+#define MESON_DEBUG_LEVEL 1
+#endif
+
+#if MESON_DEBUG_LEVEL > 0
+#define MESON_LOGV(fmt,...) ALOGV(fmt, ##__VA_ARGS__)
+#define MESON_LOGD(fmt,...) ALOGD(fmt, ##__VA_ARGS__)
+#define MESON_LOGI(fmt,...) ALOGI(fmt, ##__VA_ARGS__)
+#define MESON_LOGW(fmt,...) ALOGW(fmt, ##__VA_ARGS__)
+#else
+#define MESON_LOGV(fmt,...) ((void)0)
+#define MESON_LOGD(fmt,...) ((void)0)
+#define MESON_LOGI(fmt,...) ((void)0)
+#define MESON_LOGW(fmt,...) ((void)0)
+#endif
+#define MESON_LOGE(fmt,...) ALOGE(fmt, ##__VA_ARGS__)
+
+#if MESON_DEBUG_LEVEL > 0
+#define MESON_ASSERT(condition,fmt,...) \
+ if (!(condition)) { \
+ ALOGE(fmt, ##__VA_ARGS__); \
+ abort(); \
+ }
+#else
+#define MESON_ASSERT(condition,fmt,...) \
+ if (!(condition)) { \
+ ALOGE(fmt, ##__VA_ARGS__); \
+ }
+#endif
+
+#if MESON_DEBUG_LEVEL > 2
+#define MESON_LOG_FUN_ENTER() ALOGV("Enter %s", __func__)
+#define MESON_LOG_FUN_LEAVE() ALOGV("Leave %s", __func__)
+#else
+#define MESON_LOG_FUN_ENTER() ((void)0)
+#define MESON_LOG_FUN_LEAVE() ((void)0)
+#endif
+
+#define MESON_LOG_EMPTY_FUN() \
+ ALOGD("ERR: PLEASE FIX NON-IMPLEMENT FUN(%s).", __func__);
+
+#endif/*MESON_LOG_H*/
diff --git a/mesondisplay/include/utile.h b/mesondisplay/include/utile.h
new file mode 100644
index 0000000..d7014f5
--- a/dev/null
+++ b/mesondisplay/include/utile.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#ifndef MESON_DISPLAY_UTIL_H
+#define MESON_DISPLAY_UTIL_H
+#define DEBUG
+#ifdef DEBUG
+#include <unistd.h>
+#include <time.h>
+#define COLOR_F (getpid()%6)+1
+#define COLOR_B 8
+#ifndef RECOVERY_MODE
+#include <android/log.h>
+#define DEBUG_INFO(fmt, arg...) do { __android_log_print(ANDROID_LOG_INFO, "MesonDisplay", fmt " [in %s:%d]\n", ##arg, __func__, __LINE__);}while(0)
+#else
+#define DEBUG_INFO(fmt, arg...) do { fprintf(stderr, "[meson_display: Debug:PID[%5d]:%8ld]\033[3%d;4%dm " fmt "\033[0m [in %s:%d]\n",getpid(), time(NULL), COLOR_F, COLOR_B, ##arg, __func__, __LINE__);}while(0)
+#endif
+#else
+#define DEBUG_INFO(fmt, arg...)
+#endif //DEBUG
+
+#define DEBUG_INFO_ONCE(...) do { \
+ static int a = 1; \
+ if (a == 1) { \
+ a = 0; \
+ DEBUG_INFO(__VA_ARGS__); \
+ };} while(0)
+
+
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&) = delete; \
+ void operator=(const TypeName&) = delete
+
+#ifndef UNUSED
+#define UNUSED(s) (void)s
+#endif
+#ifndef NOTIMPLEMENTED
+#define NOTIMPLEMENTED DEBUG_INFO("Function:%s not implemented", __PRETTY_FUNCTION__);
+#endif
+#endif //MESON_DISPLAY_UTIL_H
diff --git a/mesondisplay/service/Android.mk b/mesondisplay/service/Android.mk
new file mode 100644
index 0000000..cfd03be
--- a/dev/null
+++ b/mesondisplay/service/Android.mk
@@ -0,0 +1,2 @@
+LOCAL_PATH:= $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/mesondisplay/service/DisplayService.cpp b/mesondisplay/service/DisplayService.cpp
new file mode 100644
index 0000000..03085d8
--- a/dev/null
+++ b/mesondisplay/service/DisplayService.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2020 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ * Meson display server side implement
+ */
+
+#include "DisplayService.h"
+#include "MesonLog.h"
+#include "misc.h"
+
+namespace meson{
+using namespace std;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::vendor::amlogic::display::meson_display_ipc::V1_0::Error;
+using ConnectorType = DisplayAdapter::ConnectorType;
+
+MesonIpcServer::MesonIpcServer() {
+}
+
+bool MesonIpcServer::check_recursion_record_and_push(const std::string& str) {
+ if (recursion_record.size() >= RECURSION_LIMIT) {
+ DEBUG_INFO("Service reach recursion limited(%d), show stack below", RECURSION_LIMIT);
+ //show the first str on top
+ DEBUG_INFO("%s", str.c_str());
+ while (!recursion_record.empty()) {
+ std::string stack;
+ recursion_record.top(stack);
+ DEBUG_INFO("%s", stack.c_str());
+ recursion_record.pop();
+ }
+ return false;
+ }
+ recursion_record.push(str);
+ return true;
+};
+
+Return<void> MesonIpcServer::send_msg_wait_reply(const hidl_string& msg_in, send_msg_wait_reply_cb _hidl_cb) {
+ bool ret;
+ Json::Reader reader;
+ Json::Value value, reply;
+ Json::FastWriter write;
+ hidl_string out_str;
+ const std::string tmp = msg_in.c_str();
+ DEBUG_INFO("Server(s):<<:%s:", msg_in.c_str());
+
+ if (!check_recursion_record_and_push(tmp)) {
+ _hidl_cb("");
+ return Void();
+ }
+
+ ret = reader.parse(tmp, value);
+ if (!ret) {
+ DEBUG_INFO("Server message decode error!");
+ _hidl_cb("");
+ } else {
+ message_handle(value, reply);
+ out_str = write.write(reply);
+ DEBUG_INFO("Server:>>:%s:", out_str.c_str());
+ _hidl_cb(out_str);
+ }
+ recursion_record.pop();
+ return Void();
+}
+
+Return<void> MesonIpcServer::send_msg(const hidl_string& msg_in) {
+ bool ret;
+ Json::Reader reader;
+ Json::Value value, reply;
+ const std::string tmp = msg_in.c_str();
+ DEBUG_INFO("Server:<<:%s:", msg_in.c_str());
+
+ if (!check_recursion_record_and_push(tmp)) {
+ return Void();
+ }
+
+ ret = reader.parse(tmp, value);
+ if (!ret) {
+ DEBUG_INFO("Server message decode error!");
+ } else {
+ message_handle(value, reply);
+ }
+ recursion_record.pop();
+ return Void();
+}
+
+void MesonIpcServer::message_handle(Json::Value& in, Json::Value& out) {
+ UNUSED(in);
+ UNUSED(out);
+ NOTIMPLEMENTED;
+}
+
+Return<void> MesonIpcServer::captureDisplayScreen(const int32_t displayId, const int32_t layerId,
+ captureDisplayScreen_cb hidl_cb) {
+ UNUSED(displayId);
+ UNUSED(layerId);
+ UNUSED(hidl_cb);
+ NOTIMPLEMENTED;
+ return Void();
+}
+
+DisplayServer::DisplayServer(std::unique_ptr<DisplayAdapter>& adapter) {
+ if (!adapter) {
+ DEBUG_INFO("Server create with null adapter!");
+ }
+ this->adapter = std::move(adapter);
+#if 1
+ if (registerAsService() != android::OK) {
+ DEBUG_INFO("Server RegisterAsServer failed(%d)!", registerAsService());
+ } else {
+ DEBUG_INFO("register success");
+ }
+#endif
+}
+
+void DisplayServer::message_handle(Json::Value& in, Json::Value& out) {
+ std::string cmd,tmp1;
+ Json::Value ret;
+ if (!adapter || !in.isMember("cmd")) {
+ DEBUG_INFO("Server: Display Adapter not ready or cmd formate issue!");
+ return;
+ }
+ cmd = in["cmd"].asString();
+ DEBUG_INFO("Server Handle[%s]", cmd.c_str());
+ if (cmd == "displayType") {
+ ret = adapter->displayType();
+ } else if (cmd == "getSupportDisplayModes") {
+ vector<DisplayModeInfo> displayModeList;
+ Json::Value list;
+ if (!in.isMember("p_displayType"))
+ goto OUT;
+ adapter->getSupportDisplayModes(displayModeList, (ConnectorType)in["p_displayType"].asUInt());
+ int index = 0;
+ for (auto i : displayModeList) {
+ Json::Value mode;
+ if (true == DisplayMode2Json(i, mode)) {
+ list[index++] = mode;
+ }
+ }
+ ret["displayModeList"] = list;
+ } else if (cmd == "getDisplayMode") {
+ std::string mode;
+ if (!in.isMember("p_displayType"))
+ goto OUT;
+ adapter->getDisplayMode(mode, (ConnectorType)in["p_displayType"].asUInt());
+ ret["mode"] = mode;
+ } else if (cmd == "setDisplayMode") {
+ if (!in.isMember("p_displayType") || !in.isMember("p_mode"))
+ goto OUT;
+ adapter->setDisplayMode(in["p_mode"].asString(), (ConnectorType)in["p_displayType"].asUInt());
+ } else if (cmd == "setPrefDisplayMode") {
+ if (!in.isMember("p_displayType") || !in.isMember("p_mode"))
+ goto OUT;
+ adapter->setPrefDisplayMode(in["p_mode"].asString(), (ConnectorType)in["p_displayType"].asUInt());
+ } else {
+ DEBUG_INFO("CMD not implement!");
+ }
+OUT:
+ out["ret"] = ret;
+}
+
+Return<void> DisplayServer::captureDisplayScreen(const int32_t displayId, const int32_t layerId,
+ captureDisplayScreen_cb hidl_cb) {
+ UNUSED(displayId);
+ UNUSED(layerId);
+
+ MESON_LOGD("DisplayServer captureDisplayScreen");
+ hidl_vec<hidl_handle> outHandles;
+
+ if (!adapter) {
+ MESON_LOGD("DisplayServer display Adatprer not ready");
+ outHandles.setToExternal(nullptr, 0);
+ hidl_cb(Error::NO_RESOURCES, outHandles);
+ return Void();
+ }
+
+ const native_handle_t* bufferHandle = nullptr;
+ bool ret = adapter->captureDisplayScreen(&bufferHandle);
+ if (!ret) {
+ outHandles.setToExternal(nullptr, 0);
+ hidl_cb(Error::NO_RESOURCES, outHandles);
+ return Void();
+ }
+
+ std::vector<hidl_handle> handles;
+ handles.push_back(bufferHandle);
+
+ outHandles.setToExternal(const_cast<hidl_handle*>(handles.data()), handles.size());
+ hidl_cb(Error::NONE, outHandles);
+
+ // release native handle
+ if (bufferHandle) {
+ gralloc_unref_dma_buf(const_cast<native_handle_t*> (bufferHandle));
+ gralloc_free_dma_buf(const_cast<native_handle_t*> (bufferHandle));
+ }
+ return Void();
+}
+
+} //namespace android
diff --git a/mesondisplay/service/DisplayService.h b/mesondisplay/service/DisplayService.h
new file mode 100644
index 0000000..1b8f1f7
--- a/dev/null
+++ b/mesondisplay/service/DisplayService.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#pragma once
+
+#include "DisplayAdapter.h"
+#include <json/json.h>
+#include <vendor/amlogic/display/meson_display_ipc/1.0/IMesonDisplayIPC.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include "utile.h"
+#include <stack>
+
+//Limite the server recursion.
+const int RECURSION_LIMIT = 10;
+
+namespace meson {
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+using ::vendor::amlogic::display::meson_display_ipc::V1_0::IMesonDisplayIPC;
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+using namespace std;
+
+template <typename T>
+class SafeStack {
+public:
+ SafeStack() {
+ int ret = pthread_mutex_init(&mutex, NULL);
+ if (ret)
+ DEBUG_INFO("mutex init with error!");
+ };
+ ~SafeStack() {
+ pthread_mutex_destroy(&mutex);
+ };
+ void push(const T e) {
+ pthread_mutex_lock(&mutex);
+ m_stack.push(e);
+ pthread_mutex_unlock(&mutex);
+ };
+ void pop() {
+ pthread_mutex_lock(&mutex);
+ if (!m_stack.empty())
+ m_stack.pop();
+ pthread_mutex_unlock(&mutex);
+ };
+ size_t size() {
+ size_t size;
+ pthread_mutex_lock(&mutex);
+ size = m_stack.size();
+ pthread_mutex_unlock(&mutex);
+ return size;
+ };
+ bool empty() {
+ bool ret;
+ pthread_mutex_lock(&mutex);
+ ret = m_stack.empty();
+ pthread_mutex_unlock(&mutex);
+ return ret;
+ };
+ void top(T& t) {
+ pthread_mutex_lock(&mutex);
+ t = m_stack.top();
+ pthread_mutex_unlock(&mutex);
+ };
+private:
+ pthread_mutex_t mutex;
+ std::stack<T> m_stack;
+};
+
+class MesonIpcServer : public IMesonDisplayIPC{
+public:
+ MesonIpcServer();
+ virtual ~MesonIpcServer() = default;
+ // Methods from ::vendor::amlogic::display::meson_display_ipc::V1_0::IMesonDisplayIPC follow.
+ Return<void> send_msg_wait_reply(const hidl_string& msg_in, send_msg_wait_reply_cb _hidl_cb) override;
+ Return<void> send_msg(const hidl_string& msg_in) override;
+ virtual void message_handle(Json::Value& in, Json::Value& out);
+ virtual Return<void> captureDisplayScreen(const int32_t displayId,
+ const int32_t layerId, captureDisplayScreen_cb hidl_cb) override;
+
+private:
+ bool check_recursion_record_and_push(const std::string& str);
+ SafeStack<std::string> recursion_record;
+ DISALLOW_COPY_AND_ASSIGN(MesonIpcServer);
+};
+
+
+class DisplayServer: public MesonIpcServer {
+public:
+ void message_handle(Json::Value& in, Json::Value& out) override;
+ DisplayServer(std::unique_ptr<DisplayAdapter>& adapter);
+ DisplayServer() = default;
+ Return<void> captureDisplayScreen(const int32_t displayId,
+ const int32_t layerId, captureDisplayScreen_cb hidl_cb) override;
+
+private:
+ std::unique_ptr<DisplayAdapter> adapter;
+ DISALLOW_COPY_AND_ASSIGN(DisplayServer);
+};
+
+} //namespace meson
diff --git a/mesondisplay/service/current.txt b/mesondisplay/service/current.txt
new file mode 100644
index 0000000..41146ed
--- a/dev/null
+++ b/mesondisplay/service/current.txt
@@ -0,0 +1 @@
+7e7bd3f6059a5419909d27c29c33c6a51e8362ee475fa884ca383d62d61b1b8a vendor.amlogic.display.meson_display_ipc@1.0::IMesonDisplayIPC
diff --git a/mesondisplay/service/interfaces/Android.bp b/mesondisplay/service/interfaces/Android.bp
new file mode 100644
index 0000000..3068f8c
--- a/dev/null
+++ b/mesondisplay/service/interfaces/Android.bp
@@ -0,0 +1,18 @@
+// Copyright (C) 2008 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+hidl_package_root {
+ name: "vendor.amlogic.display",
+ path: "hardware/amlogic/hwcomposer/mesondisplay/service/interfaces",
+}
diff --git a/mesondisplay/service/interfaces/meson_display_ipc/1.0/Android.bp b/mesondisplay/service/interfaces/meson_display_ipc/1.0/Android.bp
new file mode 100644
index 0000000..e43c4b4
--- a/dev/null
+++ b/mesondisplay/service/interfaces/meson_display_ipc/1.0/Android.bp
@@ -0,0 +1,18 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "vendor.amlogic.display.meson_display_ipc@1.0",
+ root: "vendor.amlogic.display",
+ srcs: [
+ "types.hal",
+ "IMesonDisplayIPC.hal",
+ ],
+ interfaces: [
+ "android.hidl.base@1.0",
+ ],
+ types: [
+ "Error",
+ ],
+ gen_java: false,
+}
+
diff --git a/mesondisplay/service/interfaces/meson_display_ipc/1.0/IMesonDisplayIPC.hal b/mesondisplay/service/interfaces/meson_display_ipc/1.0/IMesonDisplayIPC.hal
new file mode 100644
index 0000000..440a31f
--- a/dev/null
+++ b/mesondisplay/service/interfaces/meson_display_ipc/1.0/IMesonDisplayIPC.hal
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vendor.amlogic.display.meson_display_ipc@1.0;
+
+interface IMesonDisplayIPC{
+ send_msg_wait_reply(string msg_in)
+ generates (string msg_out);
+ send_msg(string msg_in);
+
+ /**
+ * Capture screen of specific layer.
+ * @param displayId is the hwc display id which now is reserved.
+ * only supoort the primary Display
+ * @param layerId is the hwc layer id which now is reserved
+ * @return error is NONE upon sucess. otherwise
+ * BAD_VALUE when the id is invalid (reserved)
+ * NO_RESOURCE when capture failed
+ * @return buffer is the return buffer handle and has the type
+ * buffer_handle_t
+ */
+ captureDisplayScreen(int32_t displayId, int32_t layerId)
+ generates (Error error,
+ vec<handle> outHandles);
+};
diff --git a/mesondisplay/service/interfaces/meson_display_ipc/1.0/types.hal b/mesondisplay/service/interfaces/meson_display_ipc/1.0/types.hal
new file mode 100644
index 0000000..746e68c
--- a/dev/null
+++ b/mesondisplay/service/interfaces/meson_display_ipc/1.0/types.hal
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vendor.amlogic.display.meson_display_ipc@1.0;
+
+/** Return codes from all functions. */
+enum Error : int32_t {
+ NONE = 0, /* no error */
+ BAD_PARAMETER = 1, /* invalid id, etc. */
+ NO_RESOURCES = 2, /* temporary failure due to resource contention */
+};
+
diff --git a/mesondisplay/test/Android.bp b/mesondisplay/test/Android.bp
new file mode 100644
index 0000000..ab3f438
--- a/dev/null
+++ b/mesondisplay/test/Android.bp
@@ -0,0 +1,27 @@
+cc_binary {
+ name: "meson_display_screencap",
+
+// cflags: [
+// "-Wall",
+// "-Werror",
+// ],
+
+ srcs: [
+ "display_screencap.cpp",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libui",
+ "libcutils",
+ "libgui",
+ "libhwui",
+ "libamgralloc_ext@2",
+ "libmeson_display_adapter_remote@1",
+ "android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
+ "android.hardware.graphics.mapper@4.0",
+ ],
+
+ clang: true,
+}
diff --git a/mesondisplay/test/display_client.cpp b/mesondisplay/test/display_client.cpp
new file mode 100644
index 0000000..72183df
--- a/dev/null
+++ b/mesondisplay/test/display_client.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#include <pthread.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+
+#include "DisplayAdapter.h"
+
+using meson::DisplayAdapter;
+using std::unique_ptr;
+
+static const char* short_option = "";
+static const struct option long_option[] = {
+ {"list-modes", no_argument, 0, 'l'},
+ {"chang-mode", required_argument, 0, 'c'},
+ {"get-property", required_argument, 0, 'g'},
+ {"set-property", required_argument, 0, 's'},
+ {"raw-cmd", required_argument, 0, 'r'},
+ {"G", required_argument, 0, 'G'},
+ {"S", required_argument, 0, 'S'},
+ {0, 0, 0, 0}
+};
+
+static void print_usage(const char* name) {
+ printf("Usage: %s [-lcrgs]\n"
+ "Get or change the mode setting of the weston drm output.\n"
+ "Options:\n"
+ " -l,--list-modes \tlist connector support modes\n"
+ " -c,--change-mode MODE \tchange connector current mode, MODE format like:%%dx%%d@%%d width,height,refresh\n"
+ " -g,--get-connector-property \"PROPERTY\"\tget connector property\n"
+ " -s,--set-connector-property \"PROPERTY\"=value\tset connector property\n"
+ " -G \"[ui-rect|display-mode]\"\tget [logic ui rect|display mode]\n"
+ " -S \"[ui-rect]\"\tset [logic ui rect]\n"
+ " \t eg: \"Content Protection\"=1\n"
+ " -r,--raw-cmd \tsend raw cmd\n", name);
+}
+
+
+int main(int argc, char* argv[]) {
+ std::vector<meson::DisplayModeInfo> displayModeList;
+ if (argc == 1) {
+ print_usage(argv[0]);
+ return 0;
+ }
+ unique_ptr<DisplayAdapter> client = meson::DisplayAdapterCreateRemote();
+ DisplayAdapter::ConnectorType type = DisplayAdapter::CONN_TYPE_HDMI;
+ DEBUG_INFO("Start client");
+
+ int opt;
+ while ((opt = getopt_long_only(argc, argv, short_option, long_option, NULL)) != -1) {
+ switch (opt) {
+ case 'l':
+ if (client->getSupportDisplayModes(displayModeList, type)) {
+ for (auto mode : displayModeList) {
+ printf("%s %u %u %u %u %f \n", mode.name.c_str(), mode.dpiX, mode.dpiY, mode.pixelW, mode.pixelH, mode.refreshRate);
+ }
+ }
+ break;
+ case 'c':
+ client->setDisplayMode(optarg, type);
+ break;
+ case 'g':
+ NOTIMPLEMENTED;
+ break;
+ case 's':
+ NOTIMPLEMENTED;
+ break;
+ case 'G':
+ if (optarg == NULL)
+ break;
+ if (0 == memcmp("display-mode", optarg, sizeof("display-mode"))) {
+ std::string mode;
+ client->getDisplayMode(mode, type);
+ printf("%s\n", mode.c_str());
+ } else {
+ NOTIMPLEMENTED;
+ }
+ break;
+ case 'S':
+ if (optarg == NULL)
+ break;
+ {
+ if (0 == memcmp("display-mode", optarg, sizeof("display-mode"))) {
+ if (optind + 1 > argc) {
+ DEBUG_INFO("miss parameter");
+ break;
+ }
+ client->setDisplayMode(argv[optind], type);
+ optind++;
+ } else {
+ NOTIMPLEMENTED;
+ }
+ }
+ break;
+ case 'r':
+ NOTIMPLEMENTED;
+ break;
+ default:
+ print_usage(argv[0]);
+ }
+ };
+
+ DEBUG_INFO("Exit client");
+ return 0;
+}
diff --git a/mesondisplay/test/display_recovery_test.cpp b/mesondisplay/test/display_recovery_test.cpp
new file mode 100644
index 0000000..6effc5e
--- a/dev/null
+++ b/mesondisplay/test/display_recovery_test.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#include <pthread.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+
+#include "DisplayAdapter.h"
+
+using meson::DisplayAdapter;
+using std::unique_ptr;
+
+static const char* short_option = "";
+static const struct option long_option[] = {
+ {"list-modes", no_argument, 0, 'l'},
+ {"chang-mode", required_argument, 0, 'c'},
+ {"get-property", required_argument, 0, 'g'},
+ {"set-property", required_argument, 0, 's'},
+ {"raw-cmd", required_argument, 0, 'r'},
+ {"G", required_argument, 0, 'G'},
+ {"S", required_argument, 0, 'S'},
+ {0, 0, 0, 0}
+};
+
+static void print_usage(const char* name) {
+ printf("Usage: %s [-lcrgs]\n"
+ "Get or change the mode setting of the weston drm output.\n"
+ "Options:\n"
+ " -l,--list-modes \tlist connector support modes\n"
+ " -c,--change-mode MODE \tchange connector current mode, MODE format like:%%dx%%d@%%d width,height,refresh\n"
+ " -g,--get-connector-property \"PROPERTY\"\tget connector property\n"
+ " -s,--set-connector-property \"PROPERTY\"=value\tset connector property\n"
+ " -G \"[ui-rect|display-mode]\"\tget [logic ui rect|display mode]\n"
+ " -S \"[ui-rect]\"\tset [logic ui rect]\n"
+ " \t eg: \"Content Protection\"=1\n"
+ " -r,--raw-cmd \tsend raw cmd\n", name);
+}
+
+
+int main(int argc, char* argv[]) {
+ std::vector<meson::DisplayModeInfo> displayModeList;
+ if (argc == 1) {
+ print_usage(argv[0]);
+ return 0;
+ }
+ unique_ptr<DisplayAdapter> client = meson::DisplayAdapterCreateLocal(meson::DisplayAdapter::BackendType::DISPLAY_TYPE_FBDEV);
+ DisplayAdapter::ConnectorType type = DisplayAdapter::CONN_TYPE_HDMI;
+ DEBUG_INFO("Start client");
+
+ int opt;
+ while ((opt = getopt_long_only(argc, argv, short_option, long_option, NULL)) != -1) {
+ switch (opt) {
+ case 'l':
+ client->getSupportDisplayModes(displayModeList, type);
+ for (auto mode : displayModeList) {
+ printf("%s %u %u %u %u %f \n", mode.name.c_str(), mode.dpiX, mode.dpiY, mode.pixelW, mode.pixelH, mode.refreshRate);
+ }
+ break;
+ case 'c':
+ client->setDisplayMode(optarg, type);
+ break;
+ case 'g':
+ NOTIMPLEMENTED;
+ break;
+ case 's':
+ NOTIMPLEMENTED;
+ break;
+ case 'G':
+ if (optarg == NULL)
+ break;
+ if (0 == memcmp("display-mode", optarg, sizeof("display-mode"))) {
+ std::string mode;
+ client->getDisplayMode(mode, type);
+ printf("%s\n", mode.c_str());
+ } else {
+ NOTIMPLEMENTED;
+ }
+ break;
+ case 'S':
+ if (optarg == NULL)
+ break;
+ {
+ if (0 == memcmp("display-mode", optarg, sizeof("display-mode"))) {
+ if (optind + 1 > argc) {
+ DEBUG_INFO("miss parameter");
+ break;
+ }
+ client->setDisplayMode(argv[optind], type);
+ optind++;
+ } else {
+ NOTIMPLEMENTED;
+ }
+ }
+ break;
+ case 'r':
+ NOTIMPLEMENTED;
+ break;
+ default:
+ print_usage(argv[0]);
+ }
+ };
+
+ DEBUG_INFO("Exit client");
+ return 0;
+}
diff --git a/mesondisplay/test/display_screencap.cpp b/mesondisplay/test/display_screencap.cpp
new file mode 100644
index 0000000..0c7dfaa
--- a/dev/null
+++ b/mesondisplay/test/display_screencap.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2020 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ * Display screen test
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <linux/fb.h>
+#include <sys/mman.h>
+
+#include <ui/Rect.h>
+#include <ui/GraphicTypes.h>
+#include <ui/PixelFormat.h>
+#include <ui/GraphicBufferMapper.h>
+#include <ui/GraphicBufferAllocator.h>
+
+#include <cutils/properties.h>
+
+#include <system/graphics.h>
+
+#include "DisplayAdapter.h"
+#include "am_gralloc_ext.h"
+//#include "misc.h"
+
+// TODO: Fix Skia.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#include <SkImageEncoder.h>
+#include <SkData.h>
+#include <SkColorSpace.h>
+#pragma GCC diagnostic pop
+
+using namespace android;
+
+static void usage(const char* pname) {
+ fprintf(stderr,
+ "usage: %s [-h] [-r] [-l layer-id] [FILENAME]\n"
+ " -h: print this message\n"
+ " -r: save as raw data or not.\n"
+ " -l: specify the hwc layer id to capture(not implement now)\n"
+ " see \"dumpsys SurfaceFlinger\" for valid layer IDS.\n"
+ "if FILENAME not given, the results will be printed to sdtout.\n",
+ pname);
+}
+
+static SkColorType flinger2skia(PixelFormat f) {
+ switch (f) {
+ case PIXEL_FORMAT_RGB_565:
+ return kRGB_565_SkColorType;
+ default:
+ return kN32_SkColorType;
+ }
+}
+
+static int32_t gralloc_unref_dma_buf(native_handle_t * hnd) {
+ static GraphicBufferMapper & maper = GraphicBufferMapper::get();
+
+ bool bfreed = false;
+ if (am_gralloc_is_valid_graphic_buffer(hnd)) {
+ if (NO_ERROR == maper.freeBuffer(hnd)) {
+ bfreed = true;
+ }
+ }
+
+ if (bfreed == false) {
+ /*may be we got handle not alloc by gralloc*/
+ native_handle_close(hnd);
+ native_handle_delete(hnd);
+ }
+
+ return 0;
+}
+
+static int32_t gralloc_lock_dma_buf(
+ native_handle_t * handle, void** vaddr) {
+ static GraphicBufferMapper & maper = GraphicBufferMapper::get();
+ uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
+ int w = am_gralloc_get_width(handle);
+ int h = am_gralloc_get_height(handle);
+
+ Rect r(w, h);
+ if (NO_ERROR == maper.lock(handle, usage, r, vaddr))
+ return 0;
+
+ fprintf(stderr, "lock buffer failed\n");
+ return -EINVAL;
+}
+
+static int32_t gralloc_unlock_dma_buf(native_handle_t * handle) {
+ static GraphicBufferMapper & maper = GraphicBufferMapper::get();
+ if (NO_ERROR == maper.unlock(handle))
+ return 0;
+ return -EINVAL;
+}
+
+int main(int argc, char **argv) {
+ const char* pname = argv[0];
+ int layerId = -1;
+ int c;
+ bool rawData = false;
+
+ while ((c = getopt(argc, argv, "rhl:")) != -1) {
+ switch (c) {
+ case 'l':
+ layerId = atoi(optarg);
+ break;
+ case 'r':
+ rawData = true;
+ break;
+ case '?':
+ case 'h':
+ usage(pname);
+ return 1;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ int fd = -1;
+ const char* fn = NULL;
+ if (argc == 0) {
+ fd = dup(STDOUT_FILENO);
+ } else if (argc == 1) {
+ fn = argv[0];
+ fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
+ if (fd == -1) {
+ fprintf(stderr, "Error opening file: %s (%s)\n", fn, strerror(errno));
+ return 1;
+ }
+ }
+
+ if (fd == -1) {
+ usage(pname);
+ return 1;
+ }
+
+ const native_handle_t *outBufferHandle = nullptr;
+ std::unique_ptr<meson::DisplayAdapter> displayAdapter = meson::DisplayAdapterCreateRemote();
+
+ if (!displayAdapter) {
+ fprintf(stderr, "DisplayAdapter init failed\n");
+ return 1;
+ }
+ displayAdapter->captureDisplayScreen(&outBufferHandle);
+
+ if (outBufferHandle == nullptr) {
+ fprintf(stderr, "capture display screen got a null buffhandle\n");
+ close(fd);
+ return 1;
+ }
+
+ fprintf(stderr, "\npassh handle nubFds %d, numInts %d\n",
+ outBufferHandle->numFds, outBufferHandle->numInts);
+
+ for (int i = 0; i < outBufferHandle->numFds; i++) {
+ fprintf(stderr, "Get naitve handle fd[%d]= %d\n", i, outBufferHandle->data[i]);
+ }
+
+ native_handle_t *bufferHandle = const_cast<native_handle_t*> (outBufferHandle);
+
+ int width = am_gralloc_get_width(bufferHandle);
+ int height = am_gralloc_get_height(bufferHandle);
+ int stride = am_gralloc_get_stride_in_pixel(bufferHandle);
+ int format = am_gralloc_get_format(bufferHandle);
+
+ size_t size = stride * height * bytesPerPixel(format);
+
+ fprintf(stderr, "format %d, (%d, %d) stride %d\n",
+ format, width, height, stride);
+ void* mapBase = nullptr;
+
+ if (gralloc_lock_dma_buf(bufferHandle, &mapBase) != 0) {
+ fprintf(stderr, "lock dma buff failed\n");
+ close(fd);
+ return 1;
+ }
+
+ if (property_get_bool("vendor.meson.display.debug", false)) {
+ sleep(30);
+ }
+ fprintf(stderr, "start screencap size=%u\n", size);
+
+ if (rawData == false) {
+ const SkImageInfo info =
+ SkImageInfo::Make(width, height, flinger2skia(format), kPremul_SkAlphaType, nullptr);
+
+ SkPixmap pixmap(info, mapBase, stride * bytesPerPixel(format));
+ struct FDWStream final : public SkWStream {
+ size_t fBytesWritten = 0;
+ int fFd;
+ FDWStream(int f) : fFd(f) {}
+ size_t bytesWritten() const override {
+ return fBytesWritten;
+ }
+ bool write(const void* buffer, size_t size) override {
+ fBytesWritten += size;
+ return size == 0 || ::write(fFd, buffer, size) > 0;
+ }
+ } fdStream(fd);
+ (void)SkEncodeImage(&fdStream, pixmap, SkEncodedImageFormat::kPNG, 100);
+ } else {
+ size_t Bpp = bytesPerPixel(format);
+ for (size_t y = 0 ; y < height ; y++) {
+ write(fd, mapBase, width*Bpp);
+ mapBase = (void *)((char *)mapBase + stride*Bpp);
+ }
+ }
+
+ close(fd);
+ // after use, need unlock and free native handle
+ gralloc_unlock_dma_buf(bufferHandle);
+ gralloc_unref_dma_buf(bufferHandle);
+
+ fprintf(stderr, "display screen cap finish!\n");
+
+ if (property_get_bool("vendor.meson.display.debug", false)) {
+ sleep(30);
+ }
+
+ return 0;
+}
diff --git a/mesondisplay/test/ipc_test.cpp b/mesondisplay/test/ipc_test.cpp
new file mode 100644
index 0000000..9407b69
--- a/dev/null
+++ b/mesondisplay/test/ipc_test.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#include "DisplayService.h"
+#include "DisplayClient.h"
+#include <sys/wait.h>
+#include <unistd.h>
+#include <hidl/HidlTransportSupport.h>
+#include <binder/ProcessState.h>
+#include <binder/IPCThreadState.h>
+#include <utils/RefBase.h>
+#include <binder/IServiceManager.h>
+#include <utils/String16.h>
+
+class ipcserver: public meson::MesonIpcServer {
+ public:
+ void message_handle(Json::Value& in, Json::Value& out) {
+ Json::FastWriter write;
+ UNUSED(in);
+ UNUSED(out);
+ DEBUG_INFO("Get message:%s", write.write(in).c_str());
+ };
+ ipcserver() {
+ DEBUG_INFO("ipcserver created");
+ if (registerAsService() != android::OK) {
+ DEBUG_INFO("RegisterAsServer failed(%d)!", registerAsService());
+ }
+ };
+ virtual ~ipcserver() = default;
+};
+
+void print_help(const char* cmd) {
+ printf("Useage:\n %s server : start a ipc server \n%s : start a ipc client test.", cmd, cmd);
+};
+
+int main(int argc, char* argv[]) {
+ UNUSED(argv);
+ print_help(argv[0]);
+ if (argc == 1) {
+ //IPC client
+ Json::Value a = "test";
+ Json::Reader reader;
+ Json::FastWriter writer;
+ bool ok = reader.parse("{ \"property\" : \"value\" }", a);
+ if (!ok) {
+ DEBUG_INFO("format error!");
+ }
+
+ auto client = meson::DisplayClient::create("meson_dispaly");
+ while (true) {
+ DEBUG_INFO("begin");
+ DEBUG_INFO("Send=>%s", writer.write(a).c_str());
+ sleep(3);
+ client->send_request(a);
+ sleep(3);
+ }
+ } else {
+ //IPC Server
+ android::ProcessState::initWithDriver("/dev/vndbinder");
+ android::hardware::configureRpcThreadpool(16, false);
+
+ static ipcserver* m_server = new ipcserver();
+ UNUSED(m_server);
+ android::IPCThreadState::self()->joinThreadPool();
+ }
+ return 0;
+};
diff --git a/mesondisplay/test/test.sh b/mesondisplay/test/test.sh
new file mode 100644
index 0000000..dbee2e3
--- a/dev/null
+++ b/mesondisplay/test/test.sh
@@ -0,0 +1,19 @@
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cycle=0
+while true;do
+ list=`meson_display_client -l|cut -d' ' -f1`;
+ let cycle++;
+
+ for mode in $list;do
+ echo -en "\rchange mode[$cycle] $(meson_display_client -G display-mode) =>$mode";
+ meson_display_client -c $mode;
+ sleep 2;
+ done
+done