common: Add hal_common_get_transport() 61/319761/4 accepted/tizen/unified/20250226.102358 accepted/tizen/unified/x/20250226.132036
authorYoungjae Cho <y0.cho@samsung.com>
Mon, 17 Feb 2025 10:04:45 +0000 (19:04 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Tue, 25 Feb 2025 08:13:47 +0000 (17:13 +0900)
The getter gets matching transport to the backend version, for example,
if a module manifest has specified transport like below
  <hal>
     <name>HAL_MODULE_FOO</name>
     <version transport="ipc">1.0</version>
     <version transport="passthrough">2.1</version>
  </hal>
and the version of installed backend module is 2.0, then the API returns
HAL_COMMON_TRANSPORT_PASSTHROUGH.

If the module has specified multiple different transports througout the
platform-version, then the latest platform-version will be returned.
For example, if a module manifest has specified transport like below
  <manifest platform-version="9.0">
     <hal>
        <name>HAL_MODULE_BAR</name>
        <version transport="passthrough">3.0</version>
     </hal>
  </manifest>
  <manifest platform-version="10.0">
     <hal>
        <name>HAL_MODULE_BAR</name>
        <version transport="ipc">3.0</version>
     </hal>
  </manifest>
then, the API returns HAL_COMMON_TRANSPORT_IPC as the transport
of latest platform-version is "ipc".

Change-Id: Iae7d46746f631634bbc461406eda8418139c2dc2
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
include/hal-common.h
src/hal-api-common.c
src/hal-api-compatibility-checker-object.c
src/hal-api-compatibility-checker-object.h
src/hal-api-compatibility-checker.c
src/hal-api-compatibility-checker.h
tests/unittest/test-hal-compatibility-checker [new file with mode: 0644]
tests/unittest/test-hal-compatibility-checker.cc

index 9b1c56d754842f2e2bb71d5f0e587ba44dc0bf8d..a9737dc6ba346adbec26a52998a8eeede72b5615 100644 (file)
@@ -312,6 +312,46 @@ int hal_common_get_supported_interface_versions(enum hal_module module,
        unsigned int **major_versions, unsigned int **minor_versions,
        enum hal_common_transport **transports, int *num_versions);
 
+/**
+ * @brief Get the transport that compatible with the current hal backend
+ * @details Compare to the hal_common_get_supported_interface_versions(), this function
+ *          is distinctive in that it returns single transport that is compatible with backend,
+ *          wherase the hal_common_get_supported_interface_versions() returns all the possible
+ *          versions and transports specified on the manifest file.
+ * @param[in] module HAL id among enum hal_module
+ * @param[out] transport The transport of version that matching to the hal backend installed
+ * @return @c 0 on success, otherwise a negative error value
+ * @code
+ *  // If a module manifest has specified transport like below, and the underlying
+ *  // backend is version of 2.0, then it returns HAL_COMMON_TRANSPORT_PASSTHROUGH.
+ *  // <hal>
+ *  //    <name>HAL_MODULE_FOO</name>
+ *  //    <version transport="ipc">1.0</version>
+ *  //    <version transport="passthrough">2.1</version>
+ *  // </hal>
+ *  int ret = hal_common_get_transport(HAL_MODULE_FOO, &transport); // HAL_COMMON_TRANSPORT_PASSTHROUGH
+ *
+ *  // If there are multiple transport throughout the platform-version, then
+ *  // the transport of the latest compatible platform-version will be returned. That is,
+ *  // if a module manifest has specified transport like below, and the underlying
+ *  // backend is version of 3.0, then it returns HAL_COMMON_TRANSPORT_IPC.
+ *  // <manifest platform-version="9.0">
+ *  //    <hal>
+ *  //       <name>HAL_MODULE_BAR</name>
+ *  //       <version transport="passthrough">3.0</version>
+ *  //    </hal>
+ *  // </manifest>
+ *  // <manifest platform-version="10.0">
+ *  //    <hal>
+ *  //       <name>HAL_MODULE_BAR</name>
+ *  //       <version transport="ipc">3.1</version>
+ *  //    </hal>
+ *  // </manifest>
+ *  int ret = hal_common_get_transport(HAL_MODULE_BAR, &transport); // HAL_COMMON_TRANSPORT_IPC
+ * @endcode
+ */
+int hal_common_get_transport(enum hal_module module, enum hal_common_transport *transport);
+
 /**
  * @}
  */
index d087c8e1d84078ecf6f6c81d920c3e7a1adef79f..8773a81018223310903566bed951be13ee24ebee 100644 (file)
@@ -783,3 +783,18 @@ int hal_common_get_supported_interface_versions(enum hal_module module,
        return hal_api_cc_get_supported_interface_versions(module,
                major_versions, minor_versions, transports, num_versions);
 }
+
+EXPORT
+int hal_common_get_transport(enum hal_module module, enum hal_common_transport *transport)
+{
+       if (!transport)
+               return -EINVAL;
+
+       if (!HALCC_ENABLED) {
+               _W("Hal compatibility checker is disabled. Always passthrough mode");
+               *transport = HAL_COMMON_TRANSPORT_PASSTHROUGH;
+               return 0;
+       }
+
+       return hal_api_cc_get_transport(module, transport);
+}
index 24393e998af552927f85159a1f8d8313852e0efb..002b380ed8a8aba3e82006bc8587b111de6ecc7f 100644 (file)
@@ -392,3 +392,32 @@ bool halcc_hal_is_compatible_with_version(halcc_hal *hal, int major, int minor)
 
        return false;
 }
+
+int halcc_hal_get_transport_by_version(halcc_hal *hal, int major, int minor, enum hal_common_transport *transport)
+{
+       int ret;
+       int version_list[64][3] = { 0 , };
+       int num_version_list = 0;
+
+       if (!hal || !transport)
+               return -EINVAL;
+
+       ret = halcc_hal_get_version_list(hal, version_list,
+               sizeof(version_list) / sizeof(version_list[0]),
+               &num_version_list);
+       if (ret < 0)
+               return ret;
+
+       for (size_t i = 0; i < num_version_list; ++i) {
+               if (version_list[i][0] != major)
+                       continue;
+
+               if (version_list[i][1] < minor)
+                       continue;
+
+               *transport = version_list[i][2];
+               return 0;
+       }
+
+       return -ENOENT;
+}
index 46466ff815d429fabc55a1d4f343cdebb9737ab8..b9cc6eac4e0f3b3638d3163e59814e2a9120565d 100644 (file)
@@ -54,6 +54,8 @@ int halcc_hal_add_version(halcc_hal *hal, int major, int minor, enum hal_common_
 int halcc_hal_get_version_list(halcc_hal *hal,
        int version_list[][3], int max_num_version_list, int *num_version_list);
 bool halcc_hal_is_compatible_with_version(halcc_hal *hal, int major, int minor);
+int halcc_hal_get_transport_by_version(halcc_hal *hal, int major, int minor,
+       enum hal_common_transport *transport);
 
 #ifdef __cplusplus
 }
index 176036f7d9d817d6a335687bad3474e764a6ac82..837b96f841ea15e5aad6aa82b2b1d966d6048c3d 100644 (file)
@@ -47,6 +47,7 @@ struct compatibility_info {
        int version_list[HALCC_NUM_VERSION_LIST_MAX][3];
        int num_version_list;
        enum hal_common_backend_compatibility compatibility;
+       enum hal_common_transport compatible_transport;
 };
 static struct compatibility_info g_compatibility_info[HAL_MODULE_END];
 
@@ -158,13 +159,22 @@ static void __convert_hal_to_info(void *data_hal, void *data_info, bool skip_ver
 
        info->compatibility = HAL_COMMON_BACKEND_COMPATIBILITY_UNKNOWN;
        ret = hal_common_get_backend_version(module, &major, &minor);
-       if (ret < 0)
+       if (ret < 0) {
+               _W("Failed to get backend version, %d", ret);
                goto out;
+       }
 
-       if (halcc_hal_is_compatible_with_version(hal, major, minor))
-               info->compatibility = HAL_COMMON_BACKEND_COMPATIBILITY_COMPATIBLE;
-       else
+       if (!halcc_hal_is_compatible_with_version(hal, major, minor)) {
+               _W("Failed to check compatibility, %d", ret);
                info->compatibility = HAL_COMMON_BACKEND_COMPATIBILITY_INCOMPATIBLE;
+               goto out;
+       }
+
+       info->compatibility = HAL_COMMON_BACKEND_COMPATIBILITY_COMPATIBLE;
+
+       ret = halcc_hal_get_transport_by_version(hal, major, minor, &info->compatible_transport);
+       if (ret < 0)
+               _W("Failed to get transport, %d", ret);
 
 out:
        info->initialized = true;
@@ -519,3 +529,26 @@ int hal_api_cc_get_supported_interface_versions(enum hal_module module,
 
        return 0;
 }
+
+int hal_api_cc_get_transport(enum hal_module module, enum hal_common_transport *transport)
+{
+       int ret;
+       struct compatibility_info info = { 0 , };
+
+       if (!transport)
+               return -EINVAL;
+
+       ret = load_module_compatibility_info(module, &info);
+       if (ret < 0) {
+               ret = load_module_compatibility_info_fallback(module, &info, false);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (info.compatibility != HAL_COMMON_BACKEND_COMPATIBILITY_COMPATIBLE)
+               return -ELIBBAD;
+
+       *transport = info.compatible_transport;
+
+       return 0;
+}
index 1dc3d98e3305e93738de0fa96a69513ae72a3cf9..41e5afb83928425cbbfe37227d884adfda0d1d55 100644 (file)
@@ -31,6 +31,7 @@ int hal_api_cc_check_backend_compatibility_by_version(enum hal_module module,
 int hal_api_cc_get_supported_interface_versions(enum hal_module module,
        unsigned int **major_versions, unsigned int **minor_versions,
        enum hal_common_transport **transports, int *num_versions);
+int hal_api_cc_get_transport(enum hal_module module, enum hal_common_transport *transport);
 
 #ifdef HAL_API_COMMON_UNITTEST /* For test use only */
 void hal_api_cc_set_compatibility_result_path(const char *path);
diff --git a/tests/unittest/test-hal-compatibility-checker b/tests/unittest/test-hal-compatibility-checker
new file mode 100644 (file)
index 0000000..e69de29
index f28c4e962dbdc1a41907f203d72e7a86831745e2..9a94e1db7481070f149ad7a30bcb922d52f85932 100644 (file)
@@ -391,3 +391,54 @@ TEST_F(HalccObjectTest, hal_get_manifest_version_transport_with_result_file)
        hal_api_cc_unset_compatibility_result_path();
        hal_api_cc_reset_compatibility_info();
 }
+
+TEST_F(HalccObjectTest, hal_get_transport_with_result_file)
+{
+       int ret;
+       enum hal_common_transport transport;
+
+       hal_api_cc_set_compatibility_result_path(g_compatibility_result_path);
+
+       mock_hal_backend_data_set_version(HAL_MODULE_TBM, 1, 0);
+
+       ret = hal_common_get_transport(HAL_MODULE_TBM, &transport);
+       ASSERT_EQ(ret, 0);
+       ASSERT_EQ(transport, HAL_COMMON_TRANSPORT_PASSTHROUGH);
+
+       /* need to reset cache as the backend version will be changed */
+       ret = truncate(g_compatibility_result_path, 0);
+       ASSERT_EQ(ret, 0);
+       hal_api_cc_reset_compatibility_info();
+
+       mock_hal_backend_data_set_version(HAL_MODULE_TBM, 2, 0);
+
+       ret = hal_common_get_transport(HAL_MODULE_TBM, &transport);
+       ASSERT_EQ(ret, 0);
+       ASSERT_EQ(transport, HAL_COMMON_TRANSPORT_IPC);
+
+       /* need to remove cache as the backend version will be changed */
+       ret = truncate(g_compatibility_result_path, 0);
+       ASSERT_EQ(ret, 0);
+       hal_api_cc_reset_compatibility_info();
+
+       mock_hal_backend_data_set_version(HAL_MODULE_TBM, 3, 0);
+
+       ret = hal_common_get_transport(HAL_MODULE_TBM, &transport);
+       ASSERT_EQ(ret, 0);
+       ASSERT_EQ(transport, HAL_COMMON_TRANSPORT_PASSTHROUGH);
+
+       /* need to remove cache as the backend version will be changed */
+       ret = truncate(g_compatibility_result_path, 0);
+       ASSERT_EQ(ret, 0);
+       hal_api_cc_reset_compatibility_info();
+
+       /* incompatible version should return error */
+       mock_hal_backend_data_set_version(HAL_MODULE_TBM, 4, 0);
+
+       ret = hal_common_get_transport(HAL_MODULE_TBM, &transport);
+       ASSERT_EQ(ret, -ELIBBAD);
+
+       unlink(g_compatibility_result_path);
+       hal_api_cc_unset_compatibility_result_path();
+       hal_api_cc_reset_compatibility_info();
+}