halapi: common: Add hal_common_(get|put)_backend() function to handle backend data 61/250461/4 accepted/tizen/unified/20210104.130218 submit/tizen/20210104.043912
authorChanwoo Choi <cw00.choi@samsung.com>
Mon, 28 Dec 2020 04:43:47 +0000 (13:43 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Mon, 28 Dec 2020 08:59:04 +0000 (17:59 +0900)
Following step is for getting the backend data which contains the
function pointers for each HAL module.
1. get library name of HAL backend
2. dlopen with library name
3. get symbol name of HAL backend
4. dlsym with symbol name
5. Get the backend data via backend->init()

In order to reduce the duplicate code on each HAL API packages,
add hal_common_get_backend() helper function which contains
the above steps to get the backend data.

And add hal_common_put_backend() helper function to free
the hal_backend instance and dlclose the shared library.

Change-Id: Ic603d3e4f0ba1ff2aed9699b1eaf925cbd97c60c
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
CMakeLists.txt
include/hal-common-interface.h
include/hal-common.h
src/common.h
src/hal-api-common.c

index 359496c..fc2b438 100644 (file)
@@ -35,7 +35,7 @@ SET(SRCS
        src/hal-api-common.c)
 
 ADD_LIBRARY( ${PROJECT_NAME} SHARED ${SRCS})
-TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${pkgs_LDFLAGS} -Wl,-z,nodelete,--no-undefined)
+TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${pkgs_LDFLAGS} -ldl -Wl,-z,nodelete,--no-undefined)
 SET_TARGET_PROPERTIES( ${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
 SET_TARGET_PROPERTIES( ${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
 
index 40ef158..56b1c3c 100644 (file)
@@ -29,6 +29,14 @@ enum hal_abi_version {
        HAL_ABI_VERSION_END,
 };
 
+typedef struct __hal_backend {
+       const char *name;
+       const char *vendor;
+       const unsigned int abi_version;
+       int (*init) (void **data);
+       void (*exit) (void *data);
+} hal_backend;
+
 #ifdef __cplusplus
 }
 #endif
index 0be04a1..e6d025c 100644 (file)
@@ -116,6 +116,22 @@ const char *hal_common_get_backend_library_name(enum hal_module handle);
 const char *hal_common_get_backend_symbol_name(enum hal_module handle);
 
 /**
+ * @brief Get the backend data according to the type of HAL module
+ * @param[in] HAL module id among enum hal_moudle
+ * @param[out] Data pointer where 'hal_backend_[module]_funcs' instance
+ *             should be stored from HAL backend binary.
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int hal_common_get_backend(enum hal_module handle, void **data);
+
+/**
+ * @brief Put the backend data according to the type of HAL module
+ * @param[in] HAL module id among enum hal_moudle
+ * @param[in] Data pointer where 'hal_backend_[module]_funcs' instance
+ */
+void hal_common_put_backend(enum hal_module handle, void *data);
+
+/**
  * @brief Check HAL ABI version whehter is suppored or not on current platform
  * @param[in] HAL module id among enum hal_moudle
  * @param[in] HAL ABI version of backend module among enum hal_abi_version
index 022e8a1..39ab920 100644 (file)
@@ -298,14 +298,18 @@ struct hal_abi_version_match {
        },
 };
 
-static const struct __hal_module_info {
+static struct __hal_module_info {
        enum hal_group group;
        enum hal_module module;
        enum hal_license license;
        char *module_name;
+
        char *library_name;
        char *library_name_64bit;
+       void *library_handle;
+       hal_backend *library_backend;
        char *symbol_name;
+
        unsigned int num_abi_versions;
        struct hal_abi_version_match *abi_versions;
 
index 205ddd5..03cb953 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <stdbool.h>
+#include <dlfcn.h>
 #include <dlog.h>
 
 #include "common.h"
@@ -71,6 +72,111 @@ const char *hal_common_get_backend_symbol_name(enum hal_module module)
 }
 
 EXPORT
+int hal_common_get_backend(enum hal_module module, void **data)
+{
+       void *handle = NULL;
+       hal_backend *backend;
+       const char *library_name, *symbol_name;
+       int ret = 0;
+
+       /* Load module */
+       library_name = hal_common_get_backend_library_name(HAL_MODULE_FOO);
+       if (!library_name) {
+               _E("Failed to get backend library name of %s\n",
+                               hal_module_info[module].module_name);
+               return TIZEN_ERROR_INVALID_PARAMETER;
+       }
+
+       handle = dlopen(library_name, RTLD_LAZY);
+       if (!handle) {
+               _E("Failed to load shared library (%s)\n", dlerror());
+               return TIZEN_ERROR_INVALID_PARAMETER;
+       }
+
+       symbol_name = hal_common_get_backend_symbol_name(HAL_MODULE_FOO);
+       if (!symbol_name) {
+               _E("Failed to get backend symbol name of %s\n",
+                               hal_module_info[module].module_name);
+               ret = TIZEN_ERROR_INVALID_PARAMETER;
+               goto err;
+       }
+
+       backend = dlsym(handle, symbol_name);
+       if (!backend) {
+               _E("Failed to find backend data (%s)\n", dlerror());
+               ret = TIZEN_ERROR_INVALID_PARAMETER;
+               goto err;
+       }
+
+       /* Print backend module and vendor name */
+
+       /* Check HAL ABI Version */
+       ret = hal_common_check_backend_abi_version(HAL_MODULE_FOO,
+                                          backend->abi_version);
+       if (ret < 0) {
+               _E("Failed to check ABI version of %s\n",
+                               hal_module_info[module].module_name);
+               ret = TIZEN_ERROR_INVALID_PARAMETER;
+               goto err;
+       }
+
+       /* Get the backend module data */
+       if (!backend->init) {
+               _E("hal_backend->init() is NULL for %s\n",
+                               hal_module_info[module].module_name);
+               ret = TIZEN_ERROR_INVALID_PARAMETER;
+               goto err;
+       }
+
+       ret = backend->init(data);
+       if (ret < 0) {
+               _E("Failed to initialize backend: name(%s)/vendor(%s)\n",
+                                       backend->name, backend->vendor);
+               ret = TIZEN_ERROR_INVALID_PARAMETER;
+               goto err;
+       }
+
+       hal_module_info[module].library_backend = backend;
+       hal_module_info[module].library_handle = handle;
+
+       _I("Get HAL backend: name(%s)/vendor(%s)\n",
+                       backend->name, backend->vendor);
+
+       return TIZEN_ERROR_NONE;
+err:
+       dlclose(handle);
+       return ret;
+}
+
+EXPORT
+void hal_common_put_backend(enum hal_module module, void *data)
+{
+       hal_backend *backend = NULL;
+       void *handle = NULL;
+       int ret;
+
+       /* Check parameter whether is valid or not */
+       if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
+               _E("Invalid parameter of HAL module (%d)\n", module);
+               return;
+       }
+
+       backend = hal_module_info[module].library_backend;
+       handle = hal_module_info[module].library_handle;
+
+       if (backend) {
+               if (backend->exit)
+                       backend->exit(data);
+
+               _I("Put HAL backend: name(%s)/vendor(%s)\n",
+                       backend->name, backend->vendor);
+       }
+
+       if (handle)
+               dlclose(handle);
+}
+
+EXPORT
 int hal_common_check_backend_abi_version(enum hal_module module,
                                enum hal_abi_version abi_version)
 {