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 359496c9086f646fd94d56fcc18c1620f6dd2679..fc2b438dd15d56750db97ed0d71e053757e0beca 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 40ef15801c5baadf26aacb3e371fd0326e6878d4..56b1c3cba2668fbcfac0e5d3a3b6ef1cc11aaebd 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 0be04a10bac7b7f1bea61de5d82e175e4f8c7775..e6d025c501e6be536b8f1f4023d3a6531210d7b6 100644 (file)
@@ -115,6 +115,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
index 022e8a17825b4fc6554bd1450f5d9da7791ee834..39ab920f9f710f093a320da5d526d32004dfdf4a 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 205ddd5ebda8b069a28960f4eed93521cabee9d2..03cb953a6c423da9c0740995bf836e661d960a36 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <stdbool.h>
+#include <dlfcn.h>
 #include <dlog.h>
 
 #include "common.h"
@@ -70,6 +71,111 @@ const char *hal_common_get_backend_symbol_name(enum hal_module module)
        return hal_module_info[module].symbol_name;
 }
 
+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)