halapi: Add new get_backend and put_backend with specific library name 98/254798/6 submit/tizen/20210316.010905
authorChanwoo Choi <cw00.choi@samsung.com>
Tue, 9 Mar 2021 05:01:59 +0000 (14:01 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Mon, 15 Mar 2021 02:41:59 +0000 (11:41 +0900)
Basically, hal_common_get_backend has used the promised libray name
for HAL backend like 'libhal-backend-[moodule name].so'. But, there are
some requirements that need to select the one HAL backend among the
multiple HAL backends on same device according to the role of use.

So that add the following two functions with new library_name argument.
- int hal_common_get_backend_with_library_name(enum hal_module module,
void **data, const char *library_name);
- int hal_common_put_backend_with_library_name(enum hal_module module,
void *data, const char *library_name);

[Constraints of library name]
This library_name argument must keep the naming rule as following:
-  'libhal-backend-[moodule name]-[extented name].so

Change-Id: Ia6c69597a718f5a4ae9de2f879f7c4337874b1ee
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
include/hal-common.h
src/common.h
src/hal-api-common.c
src/hal-api-conf.c
src/hal-api-conf.h
tests/unittest/test_hal.cc

index 7402f05f02003327bd91e76765126760e4052344..369a78a43263410582a0553eac3fe13594b5c3a8 100644 (file)
@@ -200,6 +200,27 @@ int hal_common_get_backend(enum hal_module module, void **data);
  */
 int hal_common_put_backend(enum hal_module module, void *data);
 
+/**
+ * @brief Get the backend data with the specific library name 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.
+ * @param[in] HAL backend library name which is not default library name
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int hal_common_get_backend_with_library_name(enum hal_module module,
+                                       void **data, const char *library_name);
+
+/**
+ * @brief Put the backend data with the specific library name 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
+ * @param[in] HAL backend library name which is not default library name
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int hal_common_put_backend_with_library_name(enum hal_module module,
+                                       void *data, const char *library_name);
+
 /**
  * @brief Check HAL ABI version whehter is suppored or not on current platform
  * @param[in] HAL module id among enum hal_moudle
index f19e56c66cbb6b9321fa8203fc08c75c4fa36c4a..e3463e2504069318098d07efcb7ad7583a6995a2 100644 (file)
@@ -72,8 +72,21 @@ struct __hal_module_info {
        struct hal_abi_version_match *abi_versions;
 
        bool hal_api;
+       bool hal_backend_extension;
 };
 
+static inline const char* get_backend_library_name(struct __hal_module_info *info)
+{
+       if (!info)
+               return NULL;
+
+#if defined(__aarch64__)
+       return info->library_name_64bit;
+#else
+       return info->library_name;
+#endif
+}
+
 #ifdef __cplusplus
 }
 #endif
index cc2f9262c47270787886ff5e55415a201c3ad607..9914c0891d14d83c586c00f8cc8c746ac935f355 100644 (file)
 static enum hal_abi_version g_platform_curr_abi_version;
 G_LOCK_DEFINE_STATIC(hal_common_lock);
 
-
-static const char* get_backend_library_name(struct __hal_module_info *info)
-{
-       if (!info)
-               return NULL;
-
-#if defined(__aarch64__)
-       return info->library_name_64bit;
-#else
-       return info->library_name;
-#endif
-}
-
 EXPORT
 int hal_common_get_backend_library_name(enum hal_module module, char *name, int size)
 {
@@ -64,7 +51,7 @@ int hal_common_get_backend_library_name(enum hal_module module, char *name, int
        if (_hal_api_conf_init())
                return TIZEN_ERROR_UNKNOWN;
 
-       info = _hal_api_conf_get_module_info(module);
+       info = _hal_api_conf_get_module_info(module, NULL);
        if (info == NULL) {
                _E("Failed to get HAL module(%d) information\n", module);
                ret = TIZEN_ERROR_UNKNOWN;
@@ -111,7 +98,7 @@ int hal_common_get_backend_symbol_name(enum hal_module module, char *name, int s
        if (_hal_api_conf_init())
                return TIZEN_ERROR_UNKNOWN;
 
-       info = _hal_api_conf_get_module_info(module);
+       info = _hal_api_conf_get_module_info(module, NULL);
        if (info == NULL) {
                _E("Failed to get HAL module(%d) information\n", module);
                ret = TIZEN_ERROR_UNKNOWN;
@@ -140,13 +127,13 @@ out:
        return ret;
 }
 
-EXPORT
-int hal_common_get_backend(enum hal_module module, void **data)
+static int __get_backend(enum hal_module module, void **data, const char *library_name)
 {
        struct __hal_module_info *info = NULL;
        void *handle = NULL;
        hal_backend *backend;
-       const char *library_name, *symbol_name;
+       const char *symbol_name;
+       const char *backend_library_name;
        int ret = 0;
 
        /* Check parameter whether is valid or not */
@@ -162,9 +149,13 @@ int hal_common_get_backend(enum hal_module module, void **data)
                goto err;
        }
 
-       info = _hal_api_conf_get_module_info(module);
+       info = _hal_api_conf_get_module_info(module, library_name);
        if (info == NULL) {
-               _E("Failed to get HAL module(%d) information\n", module);
+               if (!library_name)
+                       _E("Failed to get HAL module(%d) information\n", module);
+               else
+                       _E("Failed to get HAL module(%d) information (%s)\n",
+                               module, library_name);
                ret = TIZEN_ERROR_UNKNOWN;
                goto err;
        }
@@ -174,23 +165,23 @@ int hal_common_get_backend(enum hal_module module, void **data)
                 * Load HAL backend library at first loading time
                 * when usage_count is 0.
                 */
-               library_name = get_backend_library_name(info);
-               if (!library_name) {
+               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 = TIZEN_ERROR_INVALID_PARAMETER;
                        goto err;
                }
 
-               ret = access(library_name, F_OK);
+               ret = access(backend_library_name, F_OK);
                if (ret < 0) {
                        _E("%s: Failed to find backend library (%s)\n",
-                                       info->module_name, library_name);
+                                       info->module_name, backend_library_name);
                        ret = TIZEN_ERROR_INVALID_PARAMETER;
                        goto err;
                }
 
-               handle = dlopen(library_name, RTLD_LAZY);
+               handle = dlopen(backend_library_name, RTLD_LAZY);
                if (!handle) {
                        _E("%s: Failed to load backend library (%s)\n",
                                        info->module_name, dlerror());
@@ -253,7 +244,7 @@ int hal_common_get_backend(enum hal_module module, void **data)
 
        _I("%s: Get HAL backend: name(%s)/vendor(%s)/library(%s)/count(%d)\n",
                info->module_name, backend->name, backend->vendor,
-               library_name, info->usage_count);
+               backend_library_name, info->usage_count);
 
        G_UNLOCK(hal_common_lock);
        return TIZEN_ERROR_NONE;
@@ -266,8 +257,7 @@ err:
        return ret;
 }
 
-EXPORT
-int hal_common_put_backend(enum hal_module module, void *data)
+static int __put_backend(enum hal_module module, void *data, const char *library_name)
 {
        struct __hal_module_info *info = NULL;
        hal_backend *backend = NULL;
@@ -282,7 +272,7 @@ int hal_common_put_backend(enum hal_module module, void *data)
 
        G_LOCK(hal_common_lock);
 
-       info = _hal_api_conf_get_module_info(module);
+       info = _hal_api_conf_get_module_info(module, library_name);
        if (info == NULL) {
                _E("Failed to get HAL module(%d) information\n", module);
                ret =  TIZEN_ERROR_UNKNOWN;
@@ -333,6 +323,32 @@ out:
        return ret;
 }
 
+EXPORT
+int hal_common_get_backend(enum hal_module module, void **data)
+{
+       return __get_backend(module, data, NULL);
+}
+
+EXPORT
+int hal_common_put_backend(enum hal_module module, void *data)
+{
+       return __put_backend(module, data, NULL);
+}
+
+EXPORT
+int hal_common_get_backend_with_library_name(enum hal_module module,
+                                       void **data, const char *library_name)
+{
+       return __get_backend(module, data, library_name);
+}
+
+EXPORT
+int hal_common_put_backend_with_library_name(enum hal_module module,
+                                       void *data, const char *library_name)
+{
+       return __put_backend(module, data, library_name);
+}
+
 EXPORT
 int hal_common_check_backend_abi_version(enum hal_module module,
                                enum hal_abi_version abi_version)
@@ -357,7 +373,7 @@ int hal_common_check_backend_abi_version(enum hal_module module,
        if (_hal_api_conf_init())
                return TIZEN_ERROR_UNKNOWN;
 
-       info = _hal_api_conf_get_module_info(module);
+       info = _hal_api_conf_get_module_info(module, NULL);
        if (info == NULL) {
                _E("Failed to get HAL module(%d) information\n", module);
                ret = TIZEN_ERROR_UNKNOWN;
index 46d1be6e9b096e026c32cc9088066b0263add4e9..87b4c0c272b5369b24a833f5cb1f9d7ac9942c91 100644 (file)
@@ -90,13 +90,8 @@ do { \
 } while (0);
 
        struct __hal_module_info *info = (struct __hal_module_info *)data;
-       gboolean is_contained = false;
 
        if (info) {
-               is_contained = g_hash_table_contains(_module_hash, GINT_TO_POINTER(info->module));
-               if (is_contained)
-                       g_hash_table_steal(_module_hash, GINT_TO_POINTER(info->module));
-
                SAFE_FREE_AND_NULL(info->module_name);
                SAFE_FREE_AND_NULL(info->library_name);
                SAFE_FREE_AND_NULL(info->library_name_64bit);
@@ -177,8 +172,7 @@ static struct __hal_module_info *__create_hal_module_info(enum hal_module module
        return info;
 }
 
-__attribute__ ((visibility("default")))
-struct __hal_module_info* _hal_api_conf_get_module_info(enum hal_module module)
+static struct __hal_module_info* _get_module_info(enum hal_module module)
 {
        struct __hal_module_info *info = NULL;
        json_object *module_array_object = NULL;
@@ -212,6 +206,86 @@ struct __hal_module_info* _hal_api_conf_get_module_info(enum hal_module module)
        return info;
 }
 
+static struct __hal_module_info* _get_module_info_with_library_name(enum hal_module module,
+                                                               const char *library_name)
+{
+       struct __hal_module_info *info = NULL, *new_info = NULL;
+       json_object *module_array_object = NULL;
+       const char *group_name = NULL;
+       const char *module_name = NULL;
+       int ret;
+
+       if (!_json_file_object || !_module_hash | !library_name)
+               return NULL;
+
+       if (!g_str_has_prefix(library_name, "libhal-backend-")) {
+               _E("Invalid library name(%s) of HAL module(%d)\n",
+                               library_name, module);
+               return NULL;
+       }
+
+       /* Find module info with the passed library name */
+       info = (struct __hal_module_info*)g_hash_table_lookup(_module_hash,
+                                               (gpointer)library_name);
+       if (info)
+               return info;
+
+       /* Create new module info with the passed library name */
+       info = _get_module_info(module);
+       if (info == NULL) {
+               _E("Failed to get HAL module(%d) information\n", module);
+               return NULL;
+       }
+
+       new_info = (struct __hal_module_info *)calloc(1,
+                                       sizeof(struct __hal_module_info));
+       if (new_info == NULL) {
+               _E("Failed to allocate the memory\n");
+               return NULL;
+       }
+
+       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__)
+       new_info->library_name_64bit = g_strdup_printf("/hal/lib64/%s", library_name);
+#else
+       new_info->library_name = g_strdup_printf("/hal/lib/%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;
+       new_info->hal_api = info->hal_api;
+       new_info->hal_backend_extension = true;
+
+       g_hash_table_insert(_module_hash, (gpointer)library_name, new_info);
+
+       return new_info;
+}
+
+__attribute__ ((visibility("default")))
+struct __hal_module_info* _hal_api_conf_get_module_info(enum hal_module module,
+                                                       const char *library_name)
+{
+       struct __hal_module_info *info = NULL;
+       json_object *module_array_object = NULL;
+       const char *group_name = NULL;
+       const char *module_name = NULL;
+       const char *key = NULL;
+       int i;
+
+       if (!_json_file_object || !_module_hash)
+               return NULL;
+
+       if (!library_name)
+               return _get_module_info(module);
+       else
+               return _get_module_info_with_library_name(module, library_name);
+}
+
+
 enum hal_abi_version _hal_api_conf_get_platform_abi_version(void)
 {
        const char *abi_version = NULL;
index f0d0cfdb99f996f8b12992a5c2ddb4e6c3b60c87..c1e7eb9bda99660886476cce842eb1c58d5ab948 100644 (file)
@@ -33,7 +33,8 @@ extern "C" {
 int _hal_api_conf_init(void);
 void _hal_api_conf_exit(void);
 
-struct __hal_module_info *_hal_api_conf_get_module_info(enum hal_module module);
+struct __hal_module_info *_hal_api_conf_get_module_info(enum hal_module module,
+                                                       const char *library_name);
 
 enum hal_abi_version _hal_api_conf_get_platform_abi_version(void);
 
index dc3c85187fad52a269f0a78d9d21f6dadf676692..1700b6a84cf4898872854f0723ff227bbf905313 100644 (file)
@@ -391,7 +391,7 @@ TEST_P(HalInfoMatchedTest, test_group_module_matching) {
   auto result_info = GetParam();
 
   _hal_api_conf_init();
-  info = _hal_api_conf_get_module_info(result_info.module_);
+  info = _hal_api_conf_get_module_info(result_info.module_, NULL);
   ASSERT_TRUE(info != nullptr) << "module name is " << result_info.module_name_;
   EXPECT_EQ(info->group, result_info.group_) << "module name is " << result_info.module_name_;
   _hal_api_conf_exit();
@@ -403,7 +403,7 @@ TEST_P(HalInfoMatchedTest, test_license_module_matching) {
   auto result_info = GetParam();
 
   _hal_api_conf_init();
-  info = _hal_api_conf_get_module_info(result_info.module_);
+  info = _hal_api_conf_get_module_info(result_info.module_, NULL);
   ASSERT_TRUE(info != nullptr) << "module name is " << result_info.module_name_;
   EXPECT_EQ(info->license, result_info.license_) << "module name is " << result_info.module_name_;
   _hal_api_conf_exit();
@@ -415,7 +415,7 @@ TEST_P(HalInfoMatchedTest, test_module_name_matching) {
   auto result_info = GetParam();
 
   _hal_api_conf_init();
-  info = _hal_api_conf_get_module_info(result_info.module_);
+  info = _hal_api_conf_get_module_info(result_info.module_, NULL);
   ASSERT_TRUE(info != nullptr) << "module name is " << result_info.module_name_;
   EXPECT_STREQ(info->module_name, result_info.module_name_) << "module name is " << result_info.module_name_;
   _hal_api_conf_exit();
@@ -426,7 +426,7 @@ TEST_P(HalInfoMatchedTest, test_check_backend_abi_version) {
   auto result_info = GetParam();
 
   _hal_api_conf_init();
-  info = _hal_api_conf_get_module_info(result_info.module_);
+  info = _hal_api_conf_get_module_info(result_info.module_, NULL);
   ASSERT_TRUE(info != nullptr);
 
   vector<struct hal_abi_version_match> versions = result_info.versions_;