* @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);
/**
* @}
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) {
}
return hal_api_cc_get_supported_interface_versions(module,
- major_versions, minor_versions, num_versions);
+ major_versions, minor_versions, transports, num_versions);
}
#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 {
return -ENOMEM;
}
- h->transport = HALCC_TRANSPORT_DEFAULT;
-
*hal = g_steal_pointer(&h);
return 0;
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;
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;
}
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)
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) {
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) {
#include <stdbool.h>
#include <glib.h>
+#include <hal-common.h>
typedef enum halcc_manifest_type_e {
HALCC_MANIFEST_TYPE_NONE = 0,
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;
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
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) {
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);
}
}
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;
};
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)
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;
*minor_versions = ret_minor_versions;
ret_minor_versions = NULL;
+ *transports = ret_transports;
+ ret_transports = NULL;
+
*num_versions = ret_num_versions;
ret_num_versions = 0;
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);
--- /dev/null
+<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>
+
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;
struct versions_info {
unsigned int *major_versions;
unsigned int *minor_versions;
+ enum hal_common_transport *transports;
int num_versions;
};
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;
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;
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"));
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();
"Symbol Name",
"(Written by Developer)",
"(Written by Developer)",
- "Versions",
+ "Versions(Transport)",
"Version",
"Compatibility");
lshal_print_border();
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)