plugin-api: common: Add plugin-api-common 56/287856/26
authorSangYoun Kwak <sy.kwak@samsung.com>
Tue, 7 Feb 2023 06:53:24 +0000 (15:53 +0900)
committerSangYoun Kwak <sy.kwak@samsung.com>
Thu, 9 Mar 2023 07:14:28 +0000 (16:14 +0900)
plugin-api was added to provide plugin feature.
Plugin separates target-specific code to plugin-backend
from common Tizen codes such as deviced or resourced.
The structure of plugin-api is based on the hal-api.

The files newly created during build due to this patch are as follows:
(arch=armv7l)

plugin-api-common-0.1.0-0.armv7l.rpm
 * /usr/lib/: libplugin-api-common.so.0 -> libplugin-api-common.so.0.1.0
 * /usr/lib/: libplugin-api-common.so.0.1.0
 * /usr/share/licenses/plugin-api-common: LICENSE.MIT

plugin-api-common-debuginfo-0.1.0-0.armv7l
 * /usr/lib/debug/usr/lib: libplugin-api-common.so.0.1.0.debug

libsyscommon-debugsource-5.0.0-0.armv7l.rpm
 * /usr/src/debug/libsyscommon-5.0.0-0.arm/src/plugin-api/common/include: plugin-common.h
 * /usr/src/debug/libsyscommon-5.0.0-0.arm/src/plugin-api/common/include: plugin-common-interface.h
 * /usr/src/debug/libsyscommon-5.0.0-0.arm/src/plugin-api/common/src: plugin-api-list.h
 * /usr/src/debug/libsyscommon-5.0.0-0.arm/src/plugin-api/common/src: plugin-api-conf.c
 * /usr/src/debug/libsyscommon-5.0.0-0.arm/src/plugin-api/common/src: plugin-api-conf.h
 * /usr/src/debug/libsyscommon-5.0.0-0.arm/src/plugin-api/common/src: common.h
 * /usr/src/debug/libsyscommon-5.0.0-0.arm/src/plugin-api/common/src: plugin-api-common.c

plugin-api-common-devel-0.1.0-0.armv7l
 * /usr/include/plugin: plugin-common.h
 * /usr/include/plugin: plugin-common-interface.h
 * /usr/lib/: libplugin-api-common.so -> libplugin-api-common.so.0
 * /usr/lib/pkgconfig/plugin-api-common.pc
 * /usr/share/licenses/plugin-api-common: LICENSE.MIT

Change-Id: I3c0b385d7bd76b82db8db73beb189b78009b8774
Signed-off-by: SangYoun Kwak <sy.kwak@samsung.com>
CMakeLists.txt
packaging/libsyscommon.spec
src/plugin-api/common/CMakeLists.txt [new file with mode: 0644]
src/plugin-api/common/include/plugin-common-interface.h [new file with mode: 0644]
src/plugin-api/common/include/plugin-common.h [new file with mode: 0644]
src/plugin-api/common/plugin-api-common.pc.in [new file with mode: 0644]
src/plugin-api/common/src/common.h [new file with mode: 0644]
src/plugin-api/common/src/plugin-api-common.c [new file with mode: 0644]
src/plugin-api/common/src/plugin-api-conf.c [new file with mode: 0644]
src/plugin-api/common/src/plugin-api-conf.h [new file with mode: 0644]
src/plugin-api/common/src/plugin-api-list.h [new file with mode: 0644]

index ce20dbf809e5cb93ebae0ff821f76bd813222246..3e46332f1fdf6b7f21849fac1983fc9f94aebf09 100644 (file)
@@ -3,6 +3,7 @@ PROJECT(libsyscommon C)
 
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/shared)
+ADD_SUBDIRECTORY(src/plugin-api/common)
 # ADD_SUBDIRECTORY(src/libgdbus)
 
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
index 41bf65c9287f57cd7b538bee3628d50cb1eae622..c46cffade6d363c7444e34ec5e775cdc23c48d6b 100644 (file)
@@ -1,3 +1,5 @@
+%define plugin_api_common_version 0.1.0
+
 Name:           libsyscommon
 Summary:        System Libraries
 Version:        5.0.0
@@ -41,7 +43,11 @@ Development header files for system common library.
 cp %{SOURCE1001} .
 
 %build
-%cmake . -DFULLVER=%{version}
+PLUGIN_API_COMMON_MAJORVER=$(echo %{plugin_api_common_version} | cut -d'.' -f1)
+%cmake . -DFULLVER=%{version} \
+       -DPLUGIN_API_COMMON_VERSION=%{plugin_api_common_version} \
+       -DPLUGIN_API_COMMON_MAJORVER=${PLUGIN_API_COMMON_MAJORVER} \
+       -DPLUGIN_API_COMMON_ENABLE_DLOG=1
 make %{?_smp_mflags}
 
 %install
@@ -69,3 +75,42 @@ touch debugsources.list
 %{_libdir}/libsyscommon.so
 %{_includedir}/libsyscommon/*.h
 %{_libdir}/pkgconfig/libsyscommon.pc
+
+# Packages for plugin-api
+%package -n plugin-api-common
+Summary:       Common plugin APIs
+Version:       %{plugin_api_common_version}
+License:       MIT
+Requires:      pkgconfig(gio-2.0)
+Requires:      pkgconfig(dlog)
+
+%description -n plugin-api-common
+Common plugin APIs to load another APIs from backend.
+
+%files -n plugin-api-common
+%defattr(-,root,root,-)
+%license LICENSE.MIT
+%{_libdir}/libplugin-api-common.so.*
+
+%post -n plugin-api-common
+pushd %{_libdir}
+chsmack -a "_" libplugin-api-common.so.%{plugin_api_common_version}
+popd
+/sbin/ldconfig
+
+%package -n plugin-api-common-devel
+Summary:       Header files for common plugin APIs
+Version:       %{plugin_api_common_version}
+License:       MIT
+Requires:      pkgconfig(gio-2.0)
+Requires:      pkgconfig(dlog)
+
+%description -n plugin-api-common-devel
+Development header files for common plugin APIs.
+
+%files -n plugin-api-common-devel
+%defattr(-,root,root,-)
+%license LICENSE.MIT
+%{_includedir}/plugin/plugin-common*.h
+%{_libdir}/pkgconfig/plugin-api-common.pc
+%{_libdir}/libplugin-api-common.so
diff --git a/src/plugin-api/common/CMakeLists.txt b/src/plugin-api/common/CMakeLists.txt
new file mode 100644 (file)
index 0000000..326139c
--- /dev/null
@@ -0,0 +1,62 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(plugin-api-common)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "${PREFIX}/bin")
+SET(LIBDIR ${LIB_INSTALL_DIR})
+SET(INCLUDEDIR "${PREFIX}/include/plugin")
+SET(VERSION ${PLUGIN_API_COMMON_VERSION})
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+if (${PLUGIN_API_COMMON_ENABLE_DLOG})
+       ADD_DEFINITIONS("-DENABLE_DLOG=1")
+       ADD_DEFINITIONS("-DLOG_TAG=\"PLUGIN_API_COMMON\"")
+       SET(PKG_MODULES
+               dlog
+               gio-2.0
+               glib-2.0
+               )
+else()
+       SET(PKG_MODULES
+               gio-2.0
+               glib-2.0
+               )
+endif()
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED ${PKG_MODULES})
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -fPIC")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -lrt")
+SET(CMAKE_EXE_LINKER_FLAGS "-pie")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+SET(SRCS
+       src/plugin-api-common.c
+       src/plugin-api-conf.c)
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS}
+                       -ldl -Wl,-z,nodelete,--no-undefined)
+               SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${PLUGIN_API_COMMON_MAJORVER})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
+       DESTINATION ${INCLUDEDIR}
+       FILES_MATCHING PATTERN "*.h")
+
+# CONFIGURE .pc FILE
+FOREACH(include_dirs ${pkgs_INCLUDE_DIRS})
+       SET(PLUGIN_COMMON_INCLUDEDIR "${PLUGIN_COMMON_INCLUDEDIR} -I${include_dirs}")
+ENDFOREACH(include_dirs)
+FOREACH(libraries ${pkgs_LIBRARIES})
+       SET(PLUGIN_COMMON_LIBS "${PLUGIN_COMMON_LIBS} -l${libraries}")
+ENDFOREACH(libraries)
+CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
diff --git a/src/plugin-api/common/include/plugin-common-interface.h b/src/plugin-api/common/include/plugin-common-interface.h
new file mode 100644 (file)
index 0000000..37f201a
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __PLUGIN_COMMON_INTERFACE__
+#define __PLUGIN_COMMON_INTERFACE__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum plugin_abi_version {
+       PLUGIN_ABI_VERSION_UNKNOWN = 0,
+       PLUGIN_ABI_VERSION_TIZEN_7_0,
+       PLUGIN_ABI_VERSION_TIZEN_7_5,
+       PLUGIN_ABI_VERSION_END,
+};
+
+static const char *const plugin_abi_version_str[] = {
+       [PLUGIN_ABI_VERSION_UNKNOWN]    = "Unknown PLUGIN ABI Version",
+       [PLUGIN_ABI_VERSION_TIZEN_7_0]  = "PLUGIN_ABI_VERSION_TIZEN_7_0",
+       [PLUGIN_ABI_VERSION_TIZEN_7_5]  = "PLUGIN_ABI_VERSION_TIZEN_7_5",
+};
+
+typedef struct __plugin_backend {
+       const char *name;
+       const char *vendor;
+       const unsigned int abi_version;
+       int (*init) (void **data);
+       int (*exit) (void *data);
+} plugin_backend;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __PLUGIN_COMMON_INTERFACE__ */
diff --git a/src/plugin-api/common/include/plugin-common.h b/src/plugin-api/common/include/plugin-common.h
new file mode 100644 (file)
index 0000000..d7856bc
--- /dev/null
@@ -0,0 +1,153 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __PLUGIN_COMMON__
+#define __PLUGIN_COMMON__
+
+#include "plugin-common-interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum plugin_module {
+       PLUGIN_MODULE_UNKNOWN = 0,
+       PLUGIN_MODULE_RESOURCED_MEMORY_LMK,
+       PLUGIN_MODULE_END,
+};
+
+/**
+ * @brief Get the backend library name according to the type of PLUGIN module
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @param[out] Backend Library name of PLUGIN module
+ * @param[in] Arrary size of name[]
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int plugin_common_get_backend_library_name(enum plugin_module module, char *name, int size);
+
+/**
+ * @brief Get the backend symbol name according to the type of PLUGIN module
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @param[out] Backend symbol name of PLUGIN module
+ * @param[in] Arrary size of name[]
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int plugin_common_get_backend_symbol_name(enum plugin_module module, char *name, int size);
+
+/**
+ * @brief Get the backend data according to the type of PLUGIN module
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @param[out] Data pointer where 'plugin_backend_[module]_funcs' instance
+ *             should be stored from PLUGIN backend binary.
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int plugin_common_get_backend(enum plugin_module module, void **data);
+
+/**
+ * @brief Put the backend data according to the type of PLUGIN module
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @param[in] Data pointer where 'plugin_backend_[module]_funcs' instance
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int plugin_common_put_backend(enum plugin_module module, void *data);
+
+/**
+ * @brief Get the backend data with the specific library name according to the type of PLUGIN module
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @param[out] Data pointer where 'plugin_backend_[module]_funcs' instance
+ *             should be stored from PLUGIN backend binary.
+ * @param[in] PLUGIN backend library name which is not default library name
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int plugin_common_get_backend_with_library_name(enum plugin_module module,
+                                       void **data, const char *library_name);
+
+/**
+ * @brief Put the backend data with the specific library name according to the type of PLUGIN module
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @param[in] Data pointer where 'plugin_backend_[module]_funcs' instance
+ * @param[in] PLUGIN backend library name which is not default library name
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int plugin_common_put_backend_with_library_name(enum plugin_module module,
+                                       void *data, const char *library_name);
+
+/**
+ * @brief Check PLUGIN ABI version whehter is suppored or not on current platform
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @param[in] PLUGIN ABI version of backend module among enum plugin_abi_version
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int plugin_common_check_backend_abi_version(enum plugin_module module,
+                                       enum plugin_abi_version abi_version);
+
+/**
+ * @brief Get the backend PLUGIN ABI version according to the type of PLUGIN module
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @return @c positive integer value on success, otherwise a zero error value
+ */
+unsigned int plugin_common_get_backend_abi_version(enum plugin_module module);
+
+/**
+ * @brief Get the backend name according to the type of PLUGIN module
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @param[out] Backend name of PLUGIN module
+ * @param[in] Arrary size of name[]
+ * @return @c positive integer value on success, otherwise a zero error value
+ */
+int plugin_common_get_backend_name(enum plugin_module module, char *name, int size);
+
+/**
+ * @brief Get the backend vendor description according to the type of PLUGIN module
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @param[out] Backend vendor description of PLUGIN module
+ * @param[in] Arrary size of vendor[]
+ * @return @c positive integer value on success, otherwise a zero error value
+ */
+int plugin_common_get_backend_vendor(enum plugin_module module, char *vendor, int size);
+
+/**
+ * @brief Get the number of the backend libraries according to the type of PLUGIN module
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int plugin_common_get_backend_count(enum plugin_module module);
+
+/**
+ * @brief Get the backend library names according to the type of PLUGIN module
+ * @param[in] PLUGIN module id among enum plugin_moudle
+ * @param[out] Data pointer should be filled by backend library names
+ * @param[in] Number of backend library of specific PLUGIN module
+ * @param[in] Maximum length of the library name
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int plugin_common_get_backend_library_names(enum plugin_module module,
+                                       char **library_names,
+                                       int library_count,
+                                       int library_name_size);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __PLUGIN_COMMON__ */
diff --git a/src/plugin-api/common/plugin-api-common.pc.in b/src/plugin-api/common/plugin-api-common.pc.in
new file mode 100644 (file)
index 0000000..4738a7f
--- /dev/null
@@ -0,0 +1,16 @@
+# Package Information for pkg-config
+#
+# Copyright (c) 2023 Samsung Electronics Co., Ltd.
+# All rights reserved.
+#
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: plugin-api-common
+Description: Common plugin APIs
+Version: @VERSION@
+Cflags: -I${includedir} @PLUGIN_COMMON_INCLUDEDIR@
+Libs: -L${libdir} -lplugin-api-common @PLUGIN_COMMON_LIBS@
diff --git a/src/plugin-api/common/src/common.h b/src/plugin-api/common/src/common.h
new file mode 100644 (file)
index 0000000..33e4560
--- /dev/null
@@ -0,0 +1,127 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include <stdbool.h>
+
+#include "plugin-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef ENABLE_DLOG
+#include <dlog.h>
+
+#define _D(fmt, args...) SLOGD(fmt, ##args)
+#define _I(fmt, args...) SLOGI(fmt, ##args)
+#define _W(fmt, args...) SLOGW(fmt, ##args)
+#define _E(fmt, args...) SLOGE(fmt, ##args)
+#else
+#define _D(fmt, args...) do { } while(0)
+#define _I(fmt, args...) do { } while(0)
+#define _W(fmt, args...) do { } while(0)
+#define _E(fmt, args...) do { } while(0)
+#endif
+
+#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
+
+enum plugin_license {
+       PLUGIN_LICENSE_UNKNOWN = 0,
+       PLUGIN_LICENSE_APACHE_2_0,
+       PLUGIN_LICENSE_FLORA,
+       PLUGIN_LICENSE_MIT,
+       PLUGIN_LICENSE_END,
+};
+
+enum plugin_group {
+       PLUGIN_GROUP_UNKNOWN = 0,
+       PLUGIN_GROUP_RESOURCED,
+       PLUGIN_GROUP_DEVICED,
+       PLUGIN_GROUP_END,
+};
+
+static const char *const plugin_group_string[] = {
+       [PLUGIN_GROUP_UNKNOWN]          = "PLUGIN_GROUP_UNKNOWN",
+       [PLUGIN_GROUP_RESOURCED]        = "PLUGIN_GROUP_RESOURCED",
+       [PLUGIN_GROUP_DEVICED]          = "PLUGIN_GROUP_DEVICED",
+};
+
+/**
+ * plugin-api-common provides the PLUGIN ABI * (Application Binary Interface)
+ * version check feature which is used to check the ABI compatibility between
+ * PLUGIN API package and PLUGIN backend package.
+ * In order to compare ABI version between two binary, Tizen core platform
+ * always must maintain the current PLUGIN ABI version.
+ * So that, define the below global variable (g_platform_curr_abi_version).
+ *
+ * 'g_platform_curr_abi_version' will be used for all PLUGIN API modules,
+ * to check whether PLUGIN backend ABI version of each module is supported
+ * or not with current PLUGIN ABI version.
+ *
+ * 'g_platform_curr_abi_version' must be updated when Tizen platform will be
+ * released officially.
+ */
+struct plugin_abi_version_match {
+       enum plugin_abi_version platform_abi_version;
+       enum plugin_abi_version backend_min_abi_version;
+};
+
+struct __plugin_module_info {
+       int usage_count;
+
+       enum plugin_group group;
+       enum plugin_module module;
+       enum plugin_license license;
+       char *module_name;
+       char *backend_module_name;
+
+       char *library_name;
+       char *library_name_64bit;
+       void *handle;
+       plugin_backend *backend;
+       char *symbol_name;
+
+       unsigned int num_abi_versions;
+       struct plugin_abi_version_match *abi_versions;
+};
+
+static inline const char* get_backend_library_name(struct __plugin_module_info *info)
+{
+       if (!info)
+               return NULL;
+
+#if defined(__aarch64__) || defined(__x86_64__)
+       return info->library_name_64bit;
+#else
+       return info->library_name;
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __COMMON_H__ */
diff --git a/src/plugin-api/common/src/plugin-api-common.c b/src/plugin-api/common/src/plugin-api-common.c
new file mode 100644 (file)
index 0000000..0f5dcc6
--- /dev/null
@@ -0,0 +1,724 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <dlfcn.h>
+#include <dirent.h>
+#include <assert.h>
+
+#define _GNU_SOURCE
+#include <errno.h>
+
+#include <glib-object.h>
+
+#include "common.h"
+#include "plugin-api-conf.h"
+
+extern char *program_invocation_name;
+
+#ifndef EXPORT
+#define EXPORT __attribute__ ((visibility("default")))
+#endif
+
+static enum plugin_abi_version g_platform_curr_abi_version;
+G_LOCK_DEFINE_STATIC(plugin_common_lock);
+
+EXPORT
+int plugin_common_get_backend_library_name(enum plugin_module module, char *name, int size)
+{
+       const char *library_name = NULL;
+       struct __plugin_module_info *info = NULL;
+       int ret;
+       int len_library_name;
+
+       /* Check parameter whether is valid or not */
+       if (module <= PLUGIN_MODULE_UNKNOWN || module >= PLUGIN_MODULE_END) {
+               _E("Invalid parameter of PLUGIN module (%d)\n", module);
+               return -EINVAL;
+       }
+
+       if (_plugin_api_conf_init())
+               return -EINVAL;
+
+       info = _plugin_api_conf_get_module_info(module, NULL);
+       if (info == NULL) {
+               _E("Failed to get PLUGIN module(%d) information\n", module);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       library_name = get_backend_library_name(info);
+       if (!library_name) {
+               _E("%s backend library name is NULL\n", info->module_name);
+               ret = 0;
+               goto out;
+       }
+
+       len_library_name = strlen(library_name);
+       if (!name || (len_library_name + 1 > size)) {
+               ret = -EINVAL;
+               name = NULL;
+               goto out;
+       }
+       strncpy(name, library_name, size);
+
+       ret = 0;
+out:
+       _plugin_api_conf_exit();
+
+       return ret;
+}
+
+EXPORT
+int plugin_common_get_backend_symbol_name(enum plugin_module module, char *name, int size)
+{
+       struct __plugin_module_info *info = NULL;
+       char *symbol_name = NULL;
+       int ret;
+       int len_symbol_name;
+
+       /* Check parameter whether is valid or not */
+       if (module <= PLUGIN_MODULE_UNKNOWN || module >= PLUGIN_MODULE_END) {
+               _E("Invalid paramer of PLUGIN module (%d)\n", module);
+               return -EINVAL;
+       }
+
+       if (_plugin_api_conf_init())
+               return -EINVAL;
+
+       info = _plugin_api_conf_get_module_info(module, NULL);
+       if (info == NULL) {
+               _E("Failed to get PLUGIN module(%d) information\n", module);
+               ret = -EINVAL;
+               goto out;
+       }
+       symbol_name = info->symbol_name;
+       if (!symbol_name) {
+               _E("%s backend symbol name is NULL\n", info->module_name);
+               ret = 0;
+               goto out;
+       }
+
+       len_symbol_name = strlen(symbol_name);
+       if (!name || (len_symbol_name + 1 > size)) {
+               ret = -EINVAL;
+               name = NULL;
+               goto out;
+       }
+       strncpy(name, symbol_name, size);
+
+       ret = 0;
+out:
+       _plugin_api_conf_exit();
+
+       return ret;
+}
+
+static int __open_backend(struct __plugin_module_info *info)
+{
+       const char *backend_library_name = NULL;
+       int ret;
+
+       if (info->backend && info->handle)
+               return 0;
+
+       backend_library_name = get_backend_library_name(info);
+       if (!backend_library_name) {
+               _E("%s: Failed to get backend library name\n",
+                               info->module_name);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       if (access(backend_library_name, F_OK) == -1) {
+               _I("%s: There is no backend library\n",
+                               info->module_name);
+               ret = -ENOENT;
+               goto err;
+       }
+
+       if (!info->symbol_name) {
+               _E("%s: Failed to get backend symbol name\n",
+                               info->module_name);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       info->handle = dlopen(backend_library_name, RTLD_LAZY);
+       if (!info->handle) {
+               _E("%s: Failed to load backend library (%s)\n",
+                               info->module_name, dlerror());
+               ret = -EINVAL;
+               goto err;
+       }
+
+       info->backend = dlsym(info->handle, info->symbol_name);
+       if (!info->backend) {
+               _E("%s: Failed to find backend data (%s)\n",
+                               info->module_name, dlerror());
+               ret = -EINVAL;
+               goto err_dlclose;
+       }
+
+       _I("%s: Open PLUGIN backend: name(%s)|vendor(%s)|library(%s)|count(%d) by %s\n",
+               info->module_name, info->backend->name, info->backend->vendor,
+               backend_library_name, info->usage_count,
+               program_invocation_name);
+
+       return 0;
+
+err_dlclose:
+       dlclose(info->handle);
+err:
+       info->backend = NULL;
+       info->handle = NULL;
+
+       return ret;
+}
+
+static void __close_backend(struct __plugin_module_info *info)
+{
+       if (!info->backend || !info->handle)
+               return;
+
+       _I("%s: Close PLUGIN backend: name(%s)/vendor(%s)/library(%s)/count(%d) by %s\n",
+               info->module_name, info->backend->name, info->backend->vendor,
+               get_backend_library_name(info), info->usage_count,
+               program_invocation_name);
+
+       if (info->handle)
+               dlclose(info->handle);
+
+       info->backend = NULL;
+       info->handle = NULL;
+}
+
+static int __init_backend(struct __plugin_module_info *info, void **data,
+                               const char *library_name)
+{
+       int ret;
+
+       if (!info->handle || !info->backend) {
+               _I("%s: Has not yet dlopend backend\n", info->module_name);
+               return 0;
+       }
+
+       if (!info->backend->init) {
+               _E("%s: plugin_backend->init() is NULL\n", info->module_name);
+               return -EINVAL;
+       }
+
+       /* Check PLUGIN ABI Version */
+       ret = plugin_common_check_backend_abi_version(info->module,
+                                               info->backend->abi_version);
+       if (ret < 0) {
+               _E("%s: Failed to check ABI version\n", info->module_name);
+               return -EINVAL;
+       }
+
+       /* Initialize backend */
+       ret = info->backend->init(data);
+       if (ret < 0) {
+               _E("%s: Failed to initialize backend: name(%s)/vendor(%s)\n",
+                       info->module_name, info->backend->name,
+                       info->backend->vendor);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int __exit_backend(struct __plugin_module_info *info, void *data,
+                               const char *library_name)
+{
+       int ret;
+
+       if (!info->handle || !info->backend) {
+               _I("%s: Has not yet dlopend backend\n", info->module_name);
+               return 0;
+       }
+
+       /* Exit backend */
+       if (info->backend->exit) {
+               ret = info->backend->exit(data);
+               if (ret < 0) {
+                       _E("%s: Failed to exit backend: name(%s)/vendor(%s)\n",
+                               info->module_name, info->backend->name,
+                               info->backend->vendor);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int __get_backend(enum plugin_module module, void **data,
+                               const char *library_name)
+{
+       struct __plugin_module_info *info = NULL;
+       int ret;
+
+       if (module <= PLUGIN_MODULE_UNKNOWN || module >= PLUGIN_MODULE_END) {
+               _E("Invalid parameter of PLUGIN module (%d)\n", module);
+               return -EINVAL;
+       }
+
+       G_LOCK(plugin_common_lock);
+       if (_plugin_api_conf_init()) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       info = _plugin_api_conf_get_module_info(module, library_name);
+       if (info == NULL) {
+               if (!library_name)
+                       _E("Failed to get PLUGIN module(%d) information\n", module);
+               else
+                       _E("Failed to get PLUGIN module(%d) information (%s)\n",
+                               module, library_name);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       ret = __open_backend(info);
+       if (ret < 0)
+               goto err;
+
+       ret = __init_backend(info, data, NULL);
+       if (ret < 0) {
+               _E("%s: Failed to initialize the backend library\n",
+                               info->module_name);
+               ret = -EINVAL;
+               goto err_dlclose;
+       }
+
+       info->usage_count++;
+
+       _I("%s: Get PLUGIN backend: name(%s)|vendor(%s)|library(%s)|count(%d) by %s\n",
+               info->module_name, info->backend->name, info->backend->vendor,
+               get_backend_library_name(info), info->usage_count,
+               program_invocation_name);
+
+       G_UNLOCK(plugin_common_lock);
+       return 0;
+
+err_dlclose:
+       __close_backend(info);
+       _plugin_api_conf_exit();
+err:
+       G_UNLOCK(plugin_common_lock);
+       return ret;
+}
+
+static int __put_backend(enum plugin_module module, void *data,
+                               const char *library_name)
+{
+       struct __plugin_module_info *info = NULL;
+       int ret;
+
+       /* Check parameter whether is valid or not */
+       if (module <= PLUGIN_MODULE_UNKNOWN || module >= PLUGIN_MODULE_END) {
+               _E("Invalid parameter of PLUGIN module (%d)\n", module);
+               return -EINVAL;
+       }
+
+       G_LOCK(plugin_common_lock);
+
+       info = _plugin_api_conf_get_module_info(module, library_name);
+       if (info == NULL) {
+               _E("Failed to get PLUGIN module(%d) information\n", module);
+               ret =  -EINVAL;
+               goto out;
+       }
+
+       if (!info->handle || !info->backend) {
+               _I("%s: Has not yet dlopend backend\n", info->module_name);
+               ret = 0;
+               goto out;
+       }
+
+       if (!info->usage_count) {
+               _I("%s: Already fully put for PLUGIN module\n", info->module_name);
+               ret =  0;
+               goto out;
+       }
+
+       ret = __exit_backend(info, data, NULL);
+       if (ret < 0) {
+               _E("%s: Failed to exit the backend library\n",
+                               info->module_name);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       info->usage_count--;
+
+       _I("%s: Put PLUGIN backend: name(%s)/vendor(%s)/library(%s)/count(%d) by %s\n",
+               info->module_name, info->backend->name, info->backend->vendor,
+               get_backend_library_name(info), info->usage_count,
+               program_invocation_name);
+
+       if (info->usage_count > 0) {
+               ret = 0;
+               goto out;
+       }
+
+       __close_backend(info);
+       _plugin_api_conf_exit();
+
+       ret = 0;
+
+out:
+       G_UNLOCK(plugin_common_lock);
+       return ret;
+}
+
+static int __get_backend_data(enum plugin_module module, unsigned int *abi_version,
+                       char *name, int name_size, char *vendor, int vendor_size)
+{
+       struct __plugin_module_info *info = NULL;
+       int ret, len;
+
+       if (module <= PLUGIN_MODULE_UNKNOWN || module >= PLUGIN_MODULE_END) {
+               _E("Invalid parameter of PLUGIN module (%d)\n", module);
+               return 0;
+       }
+
+       G_LOCK(plugin_common_lock);
+
+       if (_plugin_api_conf_init()) {
+               ret = PLUGIN_ABI_VERSION_UNKNOWN;
+               goto err_unlock;
+       }
+
+       info = _plugin_api_conf_get_module_info(module, NULL);
+       if (info == NULL) {
+               _E("Failed to get PLUGIN module(%d) information\n", module);
+               ret = PLUGIN_ABI_VERSION_UNKNOWN;
+               goto err_conf_exit;
+       }
+
+       ret = __open_backend(info);
+       if (ret < 0)
+               goto err_conf_exit;
+
+       /* Return abi_verion of plugin_backend structure */
+       if (!name_size && !vendor_size) {
+               *abi_version = info->backend->abi_version;
+
+       /* Return name of plugin_backend structure */
+       } else if (info->backend->name && name_size && !vendor_size) {
+               len = strlen(info->backend->name);
+
+               if (!info->backend->name || (len + 1 > name_size)) {
+                       _E("%s: Invalid size of name[] array\n", info->module_name);
+                       ret = -EINVAL;
+                       goto err_conf_exit;
+               }
+
+               strncpy(name, info->backend->name, name_size);
+
+       /* Return vendor of plugin_backend structure */
+       } else if (info->backend->vendor && !name_size && vendor_size) {
+               len = strlen(info->backend->vendor);
+
+               if (!info->backend->vendor || (len + 1 > vendor_size)) {
+                       _E("%s: Invalid size of vendor[] array\n", info->module_name);
+                       ret = -EINVAL;
+                       goto err_conf_exit;
+               }
+
+               strncpy(vendor, info->backend->vendor, vendor_size);
+       } else {
+               _E("%s: Failed to get backend data\n", info->module_name);
+               ret = -EINVAL;
+               goto err_conf_exit;
+       }
+       ret = 0;
+
+err_conf_exit:
+       _plugin_api_conf_exit();
+err_unlock:
+       G_UNLOCK(plugin_common_lock);
+       return ret;
+}
+
+EXPORT
+int plugin_common_get_backend(enum plugin_module module, void **data)
+{
+       return __get_backend(module, data, NULL);
+}
+
+EXPORT
+int plugin_common_put_backend(enum plugin_module module, void *data)
+{
+       return __put_backend(module, data, NULL);
+}
+
+EXPORT
+int plugin_common_get_backend_with_library_name(enum plugin_module module,
+                                       void **data, const char *library_name)
+{
+       return __get_backend(module, data, library_name);
+}
+
+EXPORT
+int plugin_common_put_backend_with_library_name(enum plugin_module module,
+                                       void *data, const char *library_name)
+{
+       return __put_backend(module, data, library_name);
+}
+
+EXPORT
+int plugin_common_check_backend_abi_version(enum plugin_module module,
+                               enum plugin_abi_version abi_version)
+{
+       struct __plugin_module_info *info = NULL;
+       int i;
+       int ret;
+
+       /* Check parameter whether is valid or not */
+       if (module <= PLUGIN_MODULE_UNKNOWN || module >= PLUGIN_MODULE_END) {
+               _E("Invalid paramer of PLUGIN module(%d)\n", module);
+               return -EINVAL;
+       }
+
+       if (abi_version <= PLUGIN_ABI_VERSION_UNKNOWN
+                       || abi_version >= PLUGIN_ABI_VERSION_END) {
+               _E("Invalid paramer of PLUGIN ABI version(%d) for PLUGIN module(%d)\n",
+                               abi_version, module);
+               return -EINVAL;
+       }
+
+       if (_plugin_api_conf_init())
+               return -EINVAL;
+
+       info = _plugin_api_conf_get_module_info(module, NULL);
+       if (info == NULL) {
+               _E("Failed to get PLUGIN module(%d) information\n", module);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!info->num_abi_versions
+                       || !info->abi_versions) {
+               _E("%s: Doesn't have the ABI version information\n",
+                                               info->module_name);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       g_platform_curr_abi_version = _plugin_api_conf_get_platform_abi_version();
+
+       if (g_platform_curr_abi_version <= PLUGIN_ABI_VERSION_UNKNOWN
+                       || g_platform_curr_abi_version >= PLUGIN_ABI_VERSION_END) {
+               _E("Invalid paramer of current PLUGIN ABI version(%d)(%d)\n",
+                               g_platform_curr_abi_version, module);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       for (i = 0; i < info->num_abi_versions; i++) {
+               struct plugin_abi_version_match *data
+                               = &info->abi_versions[i];
+
+               if (g_platform_curr_abi_version != data->platform_abi_version)
+                       continue;
+
+               if (data->backend_min_abi_version <= PLUGIN_ABI_VERSION_UNKNOWN ||
+                       data->backend_min_abi_version >= PLUGIN_ABI_VERSION_END) {
+                       _E("%s: abi_versions[%d].backend_min_abi_version(%d) is invalid\n",
+                               info->module_name, i, data->backend_min_abi_version);
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               if (abi_version <= data->platform_abi_version
+                               && abi_version >= data->backend_min_abi_version) {
+                       ret = 0;
+                       goto out;
+               }
+
+               _E("%s: \'%s\' doesn't support \'%s\'\n",
+                               info->module_name,
+                               plugin_abi_version_str[g_platform_curr_abi_version],
+                               plugin_abi_version_str[abi_version]);
+               _E("%s: Must use ABI versions from \'%s\' to \'%s\'\n",
+                               info->module_name,
+                               plugin_abi_version_str[data->backend_min_abi_version],
+                               plugin_abi_version_str[data->platform_abi_version]);
+       }
+       ret = -EINVAL;
+
+out:
+       _plugin_api_conf_exit();
+       return ret;
+}
+
+EXPORT
+unsigned int plugin_common_get_backend_abi_version(enum plugin_module module)
+{
+       unsigned int abi_version;
+       int ret;
+
+       ret = __get_backend_data(module, &abi_version, NULL, 0, NULL, 0);
+       if (ret < 0)
+               return PLUGIN_ABI_VERSION_UNKNOWN;
+
+       return abi_version;
+}
+
+EXPORT
+int plugin_common_get_backend_name(enum plugin_module module, char *name, int size)
+{
+       return __get_backend_data(module, NULL, name, size, NULL, 0);
+}
+
+EXPORT
+int plugin_common_get_backend_vendor(enum plugin_module module, char *vendor, int size)
+{
+       return __get_backend_data(module, NULL, NULL, 0, vendor, size);
+}
+
+
+static int __get_backend_library_data(enum plugin_module module,
+                                       char **lib_names,
+                                       int lib_count,
+                                       int lib_name_size)
+{
+       struct __plugin_module_info *info = NULL;
+       struct dirent *de;
+       DIR *dir;
+       char *backend_module_name = NULL;
+       int count, i, ret;
+#if defined(__aarch64__) || defined(__x86_64__)
+       const char plugin_backend_path[] = "/usr/lib64/plugin";
+#else
+       const char plugin_backend_path[] = "/usr/lib/plugin";
+#endif
+
+       /* Check if lib_names and lib_count are valid */
+       assert(!(lib_names == NULL && lib_count != 0));
+
+       /* Check parameter whether is valid or not */
+       if (module <= PLUGIN_MODULE_UNKNOWN || module >= PLUGIN_MODULE_END) {
+               _E("Invalid parameter of PLUGIN module (%d)\n", module);
+               return -EINVAL;
+       }
+
+       if (_plugin_api_conf_init())
+               return -EINVAL;
+
+       info = _plugin_api_conf_get_module_info(module, NULL);
+       if (info == NULL) {
+               _E("Failed to get PLUGIN module(%d) information\n", module);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       if (info->backend_module_name == NULL) {
+               _E("Don't support PLUGIN backend of PLUGIN module(%s)\n",
+                                       info->module_name);
+               ret = -EINVAL;
+               goto err;
+       }
+       backend_module_name = g_strdup_printf("libplugin-backend-%s",
+                                       info->backend_module_name);
+       if (!backend_module_name) {
+               _E("Failed to allocate the backend_module_name of PLUGIN module(%s)\n",
+                                       info->module_name);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* Find PLUGIN backend libraries */
+       dir = opendir(plugin_backend_path);
+       if (!dir) {
+               _E("Failed to find PLUGIN backend path(%s) for PLUGIN module(%s)\n",
+                                       plugin_backend_path, info->module_name);
+               ret = -EINVAL;
+               goto err_free_backend_module_name;
+       }
+
+       count = 0;
+       while ((de = readdir(dir)) != NULL) {
+               if (!g_str_has_prefix(de->d_name, backend_module_name))
+                       continue;
+
+               if (lib_count == 0) {
+                       ++count;
+                       continue;
+               }
+
+               if (lib_count > 0) {
+                       strncpy(lib_names[count], de->d_name, lib_name_size - 1);
+                       lib_names[count][lib_name_size - 1] = '\0';
+
+                       ++count;
+                       continue;
+               }
+       }
+
+       if (lib_count > 0 && count != lib_count) {
+               ret = -EINVAL;
+               goto err_mismatch_count;
+       }
+
+       closedir(dir);
+       _plugin_api_conf_exit();
+       g_free(backend_module_name);
+
+       return count;
+
+err_mismatch_count:
+       for (i = count - 1; i >= 0; i--)
+               memset(lib_names[i], 0, strlen(lib_names[i]));
+
+       closedir(dir);
+err_free_backend_module_name:
+       g_free(backend_module_name);
+err:
+       _plugin_api_conf_exit();
+       return ret;
+}
+
+EXPORT
+int plugin_common_get_backend_count(enum plugin_module module)
+{
+       return __get_backend_library_data(module, NULL, 0, 0);
+}
+
+EXPORT
+int plugin_common_get_backend_library_names(enum plugin_module module,
+                                       char **library_names,
+                                       int library_count,
+                                       int library_name_size)
+{
+       int ret = __get_backend_library_data(module, library_names,
+                                       library_count, library_name_size);
+       return (ret < 0) ? ret : 0;
+}
diff --git a/src/plugin-api/common/src/plugin-api-conf.c b/src/plugin-api/common/src/plugin-api-conf.c
new file mode 100644 (file)
index 0000000..bb560a2
--- /dev/null
@@ -0,0 +1,181 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#include "plugin-common.h"
+#include "plugin-common-interface.h"
+
+#include "common.h"
+#include "plugin-api-conf.h"
+#include "plugin-api-list.h"
+
+#ifndef EXPORT
+#define EXPORT __attribute__ ((visibility("default")))
+#endif
+
+static GHashTable *_module_hash = NULL;
+
+static int _usage_count = 0;
+
+EXPORT
+void _destroy_module_info(gpointer data)
+{
+       struct __plugin_module_info *info = (struct __plugin_module_info *)data;
+
+       if (info) {
+               free(info->module_name);
+               free(info->backend_module_name);
+               free(info->library_name);
+               free(info->library_name_64bit);
+               free(info->symbol_name);
+               free(info);
+       }
+}
+
+static struct __plugin_module_info* _get_module_info(enum plugin_module module)
+{
+       return &g_plugin_module_info[module];
+}
+
+static struct __plugin_module_info* _get_module_info_with_library_name(enum plugin_module module,
+                                                               const char *library_name)
+{
+       struct __plugin_module_info *info = NULL, *new_info = NULL, *tmp_info = NULL;
+       char *library_name_prefix = NULL;
+
+       if (!_module_hash || !library_name)
+               return NULL;
+
+       tmp_info = _get_module_info(module);
+       if (tmp_info == NULL) {
+               _E("Failed to get PLUGIN module(%d) information\n", module);
+               return NULL;
+       }
+
+       if (tmp_info->backend_module_name == NULL) {
+               _E("Don't support PLUGIN backend of PLUGIN module(%s)\n",
+                               tmp_info->module_name);
+               return NULL;
+       }
+       library_name_prefix = g_strdup_printf("libplugin-backend-%s",
+                               tmp_info->backend_module_name);
+       if (!library_name_prefix) {
+               _E("Failed to allocate library_name_prefix of PLUGIN module(%s)\n",
+                               tmp_info->module_name);
+               return NULL;
+       }
+
+       if (!g_str_has_prefix(library_name, library_name_prefix)) {
+               _E("Invalid library name(%s) of PLUGIN module(%s)\n",
+                               library_name, tmp_info->module_name);
+               goto out;
+       }
+
+       /* Find module info with the passed library name */
+       info = (struct __plugin_module_info*)g_hash_table_lookup(_module_hash,
+                                               (gpointer)library_name);
+       if (info) {
+               g_free(library_name_prefix);
+               return info;
+       }
+
+       /* Create new module info with the passed library name */
+       info = tmp_info;
+
+       new_info = (struct __plugin_module_info *)calloc(1,
+                                       sizeof(struct __plugin_module_info));
+       if (new_info == NULL) {
+               _E("Failed to allocate the memory\n");
+               goto out;
+       }
+
+       new_info->usage_count = 0;
+       new_info->group = info->group;
+       new_info->module = info->module;
+       new_info->license = info->license;
+       new_info->module_name = g_strdup(info->module_name);
+#if defined(__aarch64__) || defined(__x86_64__)
+       new_info->library_name_64bit = g_strdup_printf("/usr/lib64/plugin/%s", library_name);
+#else
+       new_info->library_name = g_strdup_printf("/usr/lib/plugin/%s", library_name);
+#endif
+       new_info->symbol_name = g_strdup(info->symbol_name);
+       new_info->num_abi_versions = info->num_abi_versions;
+       new_info->abi_versions = info->abi_versions;
+
+       g_hash_table_insert(_module_hash, (gpointer)library_name, new_info);
+
+out:
+       g_free(library_name_prefix);
+
+       return new_info;
+}
+
+EXPORT
+struct __plugin_module_info* _plugin_api_conf_get_module_info(enum plugin_module module,
+                                                       const char *library_name)
+{
+       if (!_module_hash)
+               return NULL;
+
+       if (!library_name)
+               return _get_module_info(module);
+       else
+               return _get_module_info_with_library_name(module, library_name);
+}
+
+
+enum plugin_abi_version _plugin_api_conf_get_platform_abi_version(void)
+{
+       return g_platform_curr_abi_version;
+}
+
+EXPORT
+int _plugin_api_conf_init(void)
+{
+       if (_usage_count++ > 0)
+               return 0;
+
+       _module_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, _destroy_module_info);
+
+       return 0;
+}
+
+EXPORT
+void _plugin_api_conf_exit(void)
+{
+       _usage_count--;
+       if (_usage_count != 0)
+               return;
+
+       if (_module_hash) {
+               g_hash_table_remove_all(_module_hash);
+               g_hash_table_unref(_module_hash);
+               _module_hash = NULL;
+       }
+}
diff --git a/src/plugin-api/common/src/plugin-api-conf.h b/src/plugin-api/common/src/plugin-api-conf.h
new file mode 100644 (file)
index 0000000..2d59713
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __PLUGIN_API_CONF__
+#define __PLUGIN_API_CONF__
+
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#include "plugin-common-interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int _plugin_api_conf_init(void);
+void _plugin_api_conf_exit(void);
+
+struct __plugin_module_info *_plugin_api_conf_get_module_info(enum plugin_module module,
+                                                       const char *library_name);
+
+enum plugin_abi_version _plugin_api_conf_get_platform_abi_version(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __PLUGIN_API_CONF__ */
diff --git a/src/plugin-api/common/src/plugin-api-list.h b/src/plugin-api/common/src/plugin-api-list.h
new file mode 100644 (file)
index 0000000..79439fb
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __PLUGIN_API_LIST_H__
+#define __PLUGIN_API_LIST_H__
+
+#include "plugin-common.h"
+
+#include "common.h"
+
+#define PLUGIN_ABI_VERSION_MAX 10
+
+enum plugin_abi_version g_platform_curr_abi_version = PLUGIN_ABI_VERSION_TIZEN_7_5;
+
+static struct plugin_abi_version_match abi_version_match_data[PLUGIN_MODULE_END][PLUGIN_ABI_VERSION_MAX] = {
+       [PLUGIN_MODULE_RESOURCED_MEMORY_LMK] = {
+               [0] = {
+                       .platform_abi_version           = PLUGIN_ABI_VERSION_TIZEN_7_5,
+                       .backend_min_abi_version        = PLUGIN_ABI_VERSION_TIZEN_7_5,
+               },
+       },
+};
+
+static struct __plugin_module_info g_plugin_module_info[] = {
+       [PLUGIN_MODULE_RESOURCED_MEMORY_LMK] = {
+               .group                  = PLUGIN_GROUP_RESOURCED,
+               .module                 = PLUGIN_MODULE_RESOURCED_MEMORY_LMK,
+               .license                = PLUGIN_LICENSE_APACHE_2_0,
+               .module_name            = "PLUGIN_MODULE_RESOURCED_MEMORY_LMK",
+               .backend_module_name    = "resourced-memory-lmk",
+               .library_name           = "/usr/lib/plugin/libplugin-backend-resourced-memory-lmk.so",
+               .library_name_64bit     = "/usr/lib64/plugin/libplugin-backend-resourced-memory-lmk.so",
+               .symbol_name            = "plugin_backend_resourced_memory_lmk_data",
+               .num_abi_versions       = ARRAY_SIZE(abi_version_match_data[PLUGIN_MODULE_RESOURCED_MEMORY_LMK]),
+               .abi_versions           = abi_version_match_data[PLUGIN_MODULE_RESOURCED_MEMORY_LMK],
+       },
+};
+
+#endif /* __PLUGIN_API_LIST_H__ */