common: halcc: Change transport to be a property of version 54/319754/4
authorYoungjae Cho <y0.cho@samsung.com>
Mon, 17 Feb 2025 03:57:09 +0000 (12:57 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Tue, 25 Feb 2025 08:13:44 +0000 (17:13 +0900)
It is necessary to distinguish transport by version. So change the xml
tag 'transport' to be property of 'version' instead of child of 'hal'.
 • As-is: //hal/transport
    <hal>
       <version>...</version>
       <transport>...</transport>
    </hal>

 • To-be: //hal/version/@transport
    <hal>
       <version transport="...">...</version>
    </hal>

As the transport is now bound to the version, the existing API
hal_common_get_supported_interface_version() has changed to also
return transports that are associated with each version.

Additionally, lshal has changed to print transport information as well.

Change-Id: I1497d97d306f78d58477e40907ba1b570348ae47
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-parser.c
src/hal-api-compatibility-checker.c
src/hal-api-compatibility-checker.h
tests/unittest/test-hal-compatibility-checker-manifest/hal-api-tbm-manifest.xml [new file with mode: 0644]
tests/unittest/test-hal-compatibility-checker.cc
tools/lshal/lshal.c

index 912a4d8791a0f630b9c0b3d659c3fd6ef99f60ca..9b1c56d754842f2e2bb71d5f0e587ba44dc0bf8d 100644 (file)
@@ -302,10 +302,15 @@ int hal_common_check_backend_compatibility(enum hal_module module,
  * @param[out] minor_versions Array of minor version. An index is paired with the same
  *             index in the array major_versions. The caller takes ownership of the data
  *             so it is responsible for caller to free it using free()
+ * @param[out] transports Array of transport by each version. An index is paired with the
+ *             same index in the array major_versions and minor_versions. The caller takes
+ *             ownership of the data so it is responsible for caller to free it using free()
  * @param[out] num_versions Number of returned major and minor versions
+ * @return @c 0 on success, otherwise a negative error value
  */
 int hal_common_get_supported_interface_versions(enum hal_module module,
-       unsigned int **major_versions, unsigned int **minor_versions, int *num_versions);
+       unsigned int **major_versions, unsigned int **minor_versions,
+       enum hal_common_transport **transports, int *num_versions);
 
 /**
  * @}
index 1de9826bac874b2d1436ea21da2b45705b10a222..d087c8e1d84078ecf6f6c81d920c3e7a1adef79f 100644 (file)
@@ -768,9 +768,10 @@ int hal_common_check_backend_compatibility(enum hal_module module,
 
 EXPORT
 int hal_common_get_supported_interface_versions(enum hal_module module,
-       unsigned int **major_versions, unsigned int **minor_versions, int *num_versions)
+       unsigned int **major_versions, unsigned int **minor_versions,
+       enum hal_common_transport **transports, int *num_versions)
 {
-       if (!major_versions || !minor_versions || !num_versions)
+       if (!major_versions || !minor_versions || !transports || !num_versions)
                return -EINVAL;
 
        if (!HALCC_ENABLED) {
@@ -780,5 +781,5 @@ int hal_common_get_supported_interface_versions(enum hal_module module,
        }
 
        return hal_api_cc_get_supported_interface_versions(module,
-               major_versions, minor_versions, num_versions);
+               major_versions, minor_versions, transports, num_versions);
 }
index 13b13e9907d768fdd84f4d370792c00c056dd91e..24393e998af552927f85159a1f8d8313852e0efb 100644 (file)
 #include "hal-api-compatibility-checker-object.h"
 #include "hal-api-compatibility-checker-parser.h"
 
-#define HALCC_TRANSPORT_DEFAULT                HALCC_TRANSPORT_PASSTHROUGH
-
 typedef struct halcc_version {
        int major;
        int minor;
+       enum hal_common_transport transport;
 } halcc_version;
 
 typedef struct halcc_hal {
        char *name;
        halcc_version version_list[HALCC_NUM_VERSION_LIST_MAX];
        int num_version_list;
-       halcc_transport_e transport;
 } halcc_hal;
 
 typedef struct halcc_manifest {
@@ -253,8 +251,6 @@ int halcc_hal_new(halcc_hal **hal)
                return -ENOMEM;
        }
 
-       h->transport = HALCC_TRANSPORT_DEFAULT;
-
        *hal = g_steal_pointer(&h);
 
        return 0;
@@ -309,7 +305,7 @@ int halcc_hal_get_name(halcc_hal *hal, const char **hal_name)
        return 0;
 }
 
-int halcc_hal_add_version(halcc_hal *hal, int major, int minor)
+int halcc_hal_add_version(halcc_hal *hal, int major, int minor, enum hal_common_transport transport)
 {
        int i;
 
@@ -327,6 +323,16 @@ int halcc_hal_add_version(halcc_hal *hal, int major, int minor)
                if (hal->version_list[i].minor < minor)
                        hal->version_list[i].minor = minor; /* update */
 
+               /**
+                * Assume that parser must have parsed manifest in increasing
+                * order of platform-version, so assume the given transport here is
+                * the latest platform-version's. Update the transport to the latest
+                * one only when it has been specified, that is, only when it is other
+                * than HAL_COMMON_TRANSPORT_UNKNOWN.
+                */
+               if (transport != HAL_COMMON_TRANSPORT_UNKNOWN)
+                       hal->version_list[i].transport = transport;
+
                break;
        }
 
@@ -338,13 +344,14 @@ int halcc_hal_add_version(halcc_hal *hal, int major, int minor)
 
        hal->version_list[hal->num_version_list].major = major;
        hal->version_list[hal->num_version_list].minor = minor;
+       hal->version_list[hal->num_version_list].transport = transport;
 
        hal->num_version_list += 1;
 
        return 0;
 }
 
-int halcc_hal_get_version_list(halcc_hal *hal, int version_list[][2],
+int halcc_hal_get_version_list(halcc_hal *hal, int version_list[][3],
        int max_num_version_list, int *num_version_list)
 {
        if (!hal || !num_version_list)
@@ -353,6 +360,7 @@ int halcc_hal_get_version_list(halcc_hal *hal, int version_list[][2],
        for (int i = 0; i < max_num_version_list && i < hal->num_version_list; ++i) {
                version_list[i][0] = hal->version_list[i].major;
                version_list[i][1] = hal->version_list[i].minor;
+               version_list[i][2] = hal->version_list[i].transport;
        }
 
        if (hal->num_version_list > max_num_version_list) {
@@ -365,33 +373,6 @@ int halcc_hal_get_version_list(halcc_hal *hal, int version_list[][2],
        return 0;
 }
 
-int halcc_hal_set_transport(halcc_hal *hal, halcc_transport_e transport)
-{
-       if (!hal) {
-               _E("Invalid parameter\n");
-               return -EINVAL;
-       }
-
-       hal->transport = transport;
-
-       return 0;
-}
-
-int halcc_hal_get_transport(halcc_hal *hal, halcc_transport_e *transport)
-{
-       if (!hal || !transport) {
-               _E("Invalid parameter\n");
-               return -EINVAL;
-       }
-
-       assert(hal->transport >= HALCC_TRANSPORT_PASSTHROUGH);
-       assert(hal->transport <= HALCC_TRANSPORT_IPC);
-
-       *transport = hal->transport;
-
-       return 0;
-}
-
 bool halcc_hal_is_compatible_with_version(halcc_hal *hal, int major, int minor)
 {
        if (!hal) {
index 4a016a4b8e88674ed0fa176e7d8311dfe15021c6..46466ff815d429fabc55a1d4f343cdebb9737ab8 100644 (file)
@@ -23,6 +23,7 @@ extern "C" {
 
 #include <stdbool.h>
 #include <glib.h>
+#include <hal-common.h>
 
 typedef enum halcc_manifest_type_e {
        HALCC_MANIFEST_TYPE_NONE = 0,
@@ -30,12 +31,6 @@ typedef enum halcc_manifest_type_e {
        HALCC_MANIFEST_TYPE_HAL_BACKEND,
 } halcc_manifest_type_e;
 
-typedef enum halcc_transport_e {
-       HALCC_TRANSPORT_NONE = 0,
-       HALCC_TRANSPORT_PASSTHROUGH,
-       HALCC_TRANSPORT_IPC,
-} halcc_transport_e;
-
 typedef struct halcc_manifest halcc_manifest;
 typedef struct halcc_hal halcc_hal;
 
@@ -55,11 +50,9 @@ int halcc_hal_new(halcc_hal **hal);
 void halcc_hal_free(halcc_hal *hal);
 int halcc_hal_set_name(halcc_hal *hal, const char *hal_name);
 int halcc_hal_get_name(halcc_hal *hal, const char **hal_name);
-int halcc_hal_add_version(halcc_hal *hal, int major, int minor);
+int halcc_hal_add_version(halcc_hal *hal, int major, int minor, enum hal_common_transport transport);
 int halcc_hal_get_version_list(halcc_hal *hal,
-       int version_list[][2], int max_num_version_list, int *num_version_list);
-int halcc_hal_set_transport(halcc_hal *hal, halcc_transport_e transport);
-int halcc_hal_get_transport(halcc_hal *hal, halcc_transport_e *transport);
+       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);
 
 #ifdef __cplusplus
index f923fc2b324e1fc37e254454fc16964377298907..0c06d1c8dbf404fc16a08e249e88f169738807d1 100644 (file)
@@ -85,7 +85,9 @@ static int parse_hal(xmlNode *node, halcc_manifest *manifest)
                if (xmlStrEqual(child->name, "version")) {
                        int major, minor;
                        int scanned;
+                       enum hal_common_transport transport = HAL_COMMON_TRANSPORT_PASSTHROUGH;
                        __xmlchar__ xmlChar *version = xmlNodeGetContent(child);
+                       __xmlchar__ xmlChar *property = xmlGetProp(child, "transport");
 
                        scanned = sscanf(version, "%d.%d", &major, &minor);
                        if (scanned != 2) {
@@ -93,21 +95,14 @@ static int parse_hal(xmlNode *node, halcc_manifest *manifest)
                                continue;
                        }
 
-                       ret = halcc_hal_add_version(hal, major, minor);
-                       if (ret != 0)
-                               _E("Failed to halcc_hal_add_version(), ret=%d\n", ret);
-               } else if (xmlStrEqual(child->name, "transport")) {
-                       __xmlchar__ xmlChar *transport = xmlNodeGetContent(child);
-
-                       if (xmlStrEqual(transport, "passthrough"))
-                               ret = halcc_hal_set_transport(hal, HALCC_TRANSPORT_PASSTHROUGH);
-                       else if (xmlStrEqual(transport, "ipc"))
-                               ret = halcc_hal_set_transport(hal, HALCC_TRANSPORT_IPC);
-                       else
-                               ret = -EINVAL;
+                       if (xmlStrEqual(property, "passthrough"))
+                               transport = HAL_COMMON_TRANSPORT_PASSTHROUGH;
+                       else if (xmlStrEqual(property, "ipc"))
+                               transport = HAL_COMMON_TRANSPORT_IPC;
 
+                       ret = halcc_hal_add_version(hal, major, minor, transport);
                        if (ret != 0)
-                               _E("Failed to halcc_hal_set_transport(), %s, ret=%d\n", transport, ret);
+                               _E("Failed to halcc_hal_add_version(), ret=%d\n", ret);
                }
        }
 
index 6bb357466df3af87fe98f02edfcce4294dc54699..176036f7d9d817d6a335687bad3474e764a6ac82 100644 (file)
@@ -44,7 +44,7 @@
 struct compatibility_info {
        bool initialized;
        char module_name[COMPAT_INFO_MODULE_NAME_MAX];
-       int version_list[HALCC_NUM_VERSION_LIST_MAX][2];
+       int version_list[HALCC_NUM_VERSION_LIST_MAX][3];
        int num_version_list;
        enum hal_common_backend_compatibility compatibility;
 };
@@ -458,12 +458,14 @@ 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 ret;
        int ret_num_versions = 0;
        unsigned int *ret_major_versions = NULL;
        unsigned int *ret_minor_versions = NULL;
+       enum hal_common_transport *ret_transports = NULL;
        struct compatibility_info info = { 0 , };
 
        if (!major_versions || !minor_versions || !num_versions)
@@ -490,9 +492,17 @@ int hal_api_cc_get_supported_interface_versions(enum hal_module module,
                return -ENOMEM;
        }
 
+       ret_transports = calloc(ret_num_versions, sizeof(enum hal_common_transport));
+       if (!ret_transports) {
+               free(ret_major_versions);
+               free(ret_minor_versions);
+               return -ENOMEM;
+       }
+
        for (int i = 0; i < ret_num_versions; ++i) {
                ret_major_versions[i] = info.version_list[i][0];
                ret_minor_versions[i] = info.version_list[i][1];
+               ret_transports[i] = info.version_list[i][2];
        }
 
        *major_versions = ret_major_versions;
@@ -501,6 +511,9 @@ int hal_api_cc_get_supported_interface_versions(enum hal_module module,
        *minor_versions = ret_minor_versions;
        ret_minor_versions = NULL;
 
+       *transports = ret_transports;
+       ret_transports = NULL;
+
        *num_versions = ret_num_versions;
        ret_num_versions = 0;
 
index a84016fc00c85c30b004fa0986db33a1cf9ab271..1dc3d98e3305e93738de0fa96a69513ae72a3cf9 100644 (file)
@@ -29,7 +29,8 @@ int hal_api_cc_check_backend_compatibility_by_version(enum hal_module module,
        unsigned int major, unsigned int minor,
        enum hal_common_backend_compatibility *backend_compatibility);
 int hal_api_cc_get_supported_interface_versions(enum hal_module module,
-       unsigned int **major_versions, unsigned int **minor_versions, int *num_versions);
+       unsigned int **major_versions, unsigned int **minor_versions,
+       enum hal_common_transport **transports, int *num_versions);
 
 #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-manifest/hal-api-tbm-manifest.xml b/tests/unittest/test-hal-compatibility-checker-manifest/hal-api-tbm-manifest.xml
new file mode 100644 (file)
index 0000000..5fc2e1d
--- /dev/null
@@ -0,0 +1,31 @@
+<hal-api>
+       <manifest platform-version="9.0">
+               <hal-module>
+                       <name>HAL_MODULE_TBM</name>
+                       <version>1.0</version>
+                       <version transport="passthrough">2.0</version>
+               </hal-module>
+       </manifest>
+       <manifest platform-version="10.0">
+               <hal-module>
+                       <name>HAL_MODULE_TBM</name>
+                       <version transport="ipc">2.0</version>
+                       <version transport="passthrough">3.0</version>
+               </hal-module>
+       </manifest>
+       <manifest platform-version="11.0">
+               <hal-module>
+                       <name>HAL_MODULE_TBM</name>
+                       <version transport="ipc">2.1</version>
+                       <version transport="passthrough">3.0</version>
+               </hal-module>
+       </manifest>
+       <manifest platform-version="12.0">
+               <hal-module>
+                       <name>HAL_MODULE_TBM</name>
+                       <version transport="ipc">2.1</version>
+                       <version>3.1</version>
+               </hal-module>
+       </manifest>
+</hal-api>
+
index c7174a6fa96bff8c826f18edb0b55ae369fb2642..f28c4e962dbdc1a41907f203d72e7a86831745e2 100644 (file)
@@ -100,7 +100,7 @@ char* HalccObjectTest::g_cwd = NULL;
 
 static bool have_exact_version_within_halcc_hal(halcc_hal *hal, const char *version)
 {
-       int version_list[HALCC_NUM_VERSION_LIST_MAX][2] = { 0 , };
+       int version_list[HALCC_NUM_VERSION_LIST_MAX][3] = { 0 , };
        int num_version_list = 0;
        int major, minor;
        int ret;
@@ -129,6 +129,7 @@ static bool have_exact_version_within_halcc_hal(halcc_hal *hal, const char *vers
 struct versions_info {
        unsigned int *major_versions;
        unsigned int *minor_versions;
+       enum hal_common_transport *transports;
        int num_versions;
 };
 
@@ -158,6 +159,35 @@ static bool have_exact_version_within_array(const struct versions_info *vi, cons
        return false;
 }
 
+static bool have_exact_version_transport_within_array(const struct versions_info *vi,
+       const char *version, enum hal_common_transport transport)
+{
+       unsigned int major, minor;
+       int ret;
+
+       if (!vi)
+               return false;
+
+       if (!vi->major_versions || !vi->minor_versions)
+               return false;
+
+       ret = sscanf(version, "%u.%u", &major, &minor);
+               if (ret != 2)
+                       return false;
+
+       for (int i = 0; i < vi->num_versions; ++i) {
+               if (vi->major_versions[i] != major)
+                       continue;
+               if (vi->minor_versions[i] != minor)
+                       continue;
+               if (vi->transports[i] != transport)
+                       continue;
+               return true;
+       }
+
+       return false;
+}
+
 MATCHER_P(HasExactVersionHalccHal, version, "")
 {
        halcc_hal *hal = (halcc_hal *) arg;
@@ -179,6 +209,13 @@ MATCHER_P(HasExactVersionArray, version, "")
        return have_exact_version_within_array(vi, version);
 }
 
+MATCHER_P2(HasExactVersionTransportArray, version, transport, "")
+{
+       const struct versions_info *vi = (const struct versions_info *) arg;
+
+       return have_exact_version_transport_within_array(vi, version, transport);
+}
+
 TEST_F(HalccObjectTest, manifest_find_hal_success)
 {
        halcc_hal *hal = NULL;
@@ -302,7 +339,7 @@ TEST_F(HalccObjectTest, hal_get_manifest_version_success_with_result_file)
        ASSERT_EQ(ret, 0);
 
        ret = hal_common_get_supported_interface_versions(HAL_MODULE_DEVICE_DISPLAY,
-               &vi.major_versions, &vi.minor_versions, &vi.num_versions);
+               &vi.major_versions, &vi.minor_versions, &vi.transports, &vi.num_versions);
        ASSERT_EQ(ret, 0);
 
        ASSERT_THAT(&vi, HasExactVersionArray("1.2"));
@@ -315,6 +352,41 @@ TEST_F(HalccObjectTest, hal_get_manifest_version_success_with_result_file)
        free(vi.minor_versions);
        vi.minor_versions = NULL;
 
+       free(vi.transports);
+       vi.transports = NULL;
+
+       unlink(g_compatibility_result_path);
+       hal_api_cc_unset_compatibility_result_path();
+       hal_api_cc_reset_compatibility_info();
+}
+
+TEST_F(HalccObjectTest, hal_get_manifest_version_transport_with_result_file)
+{
+       int ret;
+       struct versions_info vi = { 0 , };
+
+       hal_api_cc_set_compatibility_result_path(g_compatibility_result_path);
+
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
+       ASSERT_EQ(ret, 0);
+
+       ret = hal_common_get_supported_interface_versions(HAL_MODULE_TBM,
+                       &vi.major_versions, &vi.minor_versions, &vi.transports, &vi.num_versions);
+       ASSERT_EQ(ret, 0);
+
+       ASSERT_THAT(&vi, HasExactVersionTransportArray("1.0", HAL_COMMON_TRANSPORT_PASSTHROUGH)); /* default : PASSTHROUGH */
+       ASSERT_THAT(&vi, HasExactVersionTransportArray("2.1", HAL_COMMON_TRANSPORT_IPC));
+       ASSERT_THAT(&vi, HasExactVersionTransportArray("3.1", HAL_COMMON_TRANSPORT_PASSTHROUGH));
+
+       free(vi.major_versions);
+       vi.major_versions = NULL;
+
+       free(vi.minor_versions);
+       vi.minor_versions = NULL;
+
+       free(vi.minor_versions);
+       vi.minor_versions = NULL;
+
        unlink(g_compatibility_result_path);
        hal_api_cc_unset_compatibility_result_path();
        hal_api_cc_reset_compatibility_info();
index 7ce8aa415d16299e0a8d870bbdb3b165e83a5168..daf408fac09e145078f06b6489f390f2a1d597a8 100644 (file)
@@ -82,7 +82,7 @@ static void lshal_print_hal_backend_info(u_int32_t flags) {
                        "Symbol Name",
                        "(Written by Developer)",
                        "(Written by Developer)",
-                       "Versions",
+                       "Versions(Transport)",
                        "Version",
                        "Compatibility");
        lshal_print_border();
@@ -149,29 +149,38 @@ static void lshal_print_hal_backend_info(u_int32_t flags) {
                if (LSHAL_FLAG_MANIFEST_VERSION & flags) {
                        unsigned int *major_versions = NULL;
                        unsigned int *minor_versions = NULL;
+                       enum hal_common_transport *transports = NULL;
                        int num_versions = 0;
 
                        strncpy(str, "", BUFF_MAX - 1);
 
                        ret = hal_common_get_supported_interface_versions(module,
-                               &major_versions, &minor_versions, &num_versions);
+                               &major_versions, &minor_versions, &transports, &num_versions);
                        if (ret < 0) {
                                printf(" %-25s |", "");
                        } else {
                                char *pos = str;
                                char *const end = pos + sizeof(str);
                                for (int i = 0; i < num_versions; ++i) {
+                                       const char *transport;
+
                                        if (pos >= end)
                                                break;
 
-                                       pos += snprintf(pos, end - pos, "%u.%u, ",
-                                               major_versions[i], minor_versions[i]);
+                                       transport = (transports[i] == HAL_COMMON_TRANSPORT_IPC ? "ipc"
+                                                : transports[i] == HAL_COMMON_TRANSPORT_PASSTHROUGH ? "passthrough"
+                                                : "Unknown");
+
+                                       pos += snprintf(pos, end - pos, "%u.%u(%s), ",
+                                               major_versions[i], minor_versions[i], transport);
                                }
 
                                free(major_versions);
                                major_versions = NULL;
                                free(minor_versions);
                                minor_versions = NULL;
+                               free(transports);
+                               transports = NULL;
 
                                /* Remove trailing ',' and terminate the string */
                                if (pos < end)