don't loas inapropriate HAL for a device.
Once we have determined which HAL to load and checked that the library exists, we should not try to load another (more generic) HAL if a failure occurs, because this could result in different process using different HALs for the same component. Instead we just return an error.
This commit is contained in:
44
hardware.c
44
hardware.c
@@ -41,15 +41,17 @@
|
|||||||
* led.default.so
|
* led.default.so
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define HAL_DEFAULT_VARIANT "default"
|
|
||||||
static const char *variant_keys[] = {
|
static const char *variant_keys[] = {
|
||||||
"ro.hardware", /* This goes first so that it can pick up a different
|
"ro.hardware", /* This goes first so that it can pick up a different
|
||||||
file on the emulator. */
|
file on the emulator. */
|
||||||
"ro.product.board",
|
"ro.product.board",
|
||||||
"ro.board.platform",
|
"ro.board.platform",
|
||||||
"ro.arch"
|
"ro.arch",
|
||||||
|
"default"
|
||||||
};
|
};
|
||||||
#define HAL_VARIANT_KEYS_COUNT (sizeof(variant_keys)/sizeof(variant_keys[0]))
|
|
||||||
|
static const int HAL_VARIANT_KEYS_COUNT =
|
||||||
|
(sizeof(variant_keys)/sizeof(variant_keys[0]));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the file defined by the variant and if successful
|
* Load the file defined by the variant and if successful
|
||||||
@@ -57,16 +59,12 @@ static const char *variant_keys[] = {
|
|||||||
* @return 0 = success, !0 = failure.
|
* @return 0 = success, !0 = failure.
|
||||||
*/
|
*/
|
||||||
static int load(const char *id,
|
static int load(const char *id,
|
||||||
const char *variant,
|
const char *path,
|
||||||
const struct hw_module_t **pHmi)
|
const struct hw_module_t **pHmi)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
void *handle;
|
void *handle;
|
||||||
struct hw_module_t *hmi;
|
struct hw_module_t *hmi;
|
||||||
char path[PATH_MAX];
|
|
||||||
|
|
||||||
/* Construct the path. */
|
|
||||||
snprintf(path, sizeof(path), "%s/%s.%s.so", HAL_LIBRARY_PATH, id, variant);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* load the symbols resolving undefined symbols before
|
* load the symbols resolving undefined symbols before
|
||||||
@@ -76,7 +74,7 @@ static int load(const char *id,
|
|||||||
handle = dlopen(path, RTLD_NOW);
|
handle = dlopen(path, RTLD_NOW);
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
char const *err_str = dlerror();
|
char const *err_str = dlerror();
|
||||||
//LOGW("load: module=%s error=%s", path, err_str);
|
LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
|
||||||
status = -EINVAL;
|
status = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -85,7 +83,6 @@ static int load(const char *id,
|
|||||||
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
|
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
|
||||||
hmi = (struct hw_module_t *)dlsym(handle, sym);
|
hmi = (struct hw_module_t *)dlsym(handle, sym);
|
||||||
if (hmi == NULL) {
|
if (hmi == NULL) {
|
||||||
char const *err_str = dlerror();
|
|
||||||
LOGE("load: couldn't find symbol %s", sym);
|
LOGE("load: couldn't find symbol %s", sym);
|
||||||
status = -EINVAL;
|
status = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
@@ -103,7 +100,7 @@ static int load(const char *id,
|
|||||||
/* success */
|
/* success */
|
||||||
status = 0;
|
status = 0;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
hmi = NULL;
|
hmi = NULL;
|
||||||
if (handle != NULL) {
|
if (handle != NULL) {
|
||||||
@@ -112,7 +109,7 @@ done:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
|
LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
|
||||||
id, path, *pHmi, handle);
|
id, path, *pHmi, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
*pHmi = hmi;
|
*pHmi = hmi;
|
||||||
@@ -126,6 +123,7 @@ int hw_get_module(const char *id, const struct hw_module_t **module)
|
|||||||
int i;
|
int i;
|
||||||
const struct hw_module_t *hmi = NULL;
|
const struct hw_module_t *hmi = NULL;
|
||||||
char prop[PATH_MAX];
|
char prop[PATH_MAX];
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here we rely on the fact that calling dlopen multiple times on
|
* Here we rely on the fact that calling dlopen multiple times on
|
||||||
@@ -134,21 +132,25 @@ int hw_get_module(const char *id, const struct hw_module_t **module)
|
|||||||
* We also assume that dlopen() is thread-safe.
|
* We also assume that dlopen() is thread-safe.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
status = -EINVAL;
|
|
||||||
|
|
||||||
/* Loop through the configuration variants looking for a module */
|
/* Loop through the configuration variants looking for a module */
|
||||||
for (i = 0; (status != 0) && (i < HAL_VARIANT_KEYS_COUNT); i++) {
|
for (i=0 ; i<HAL_VARIANT_KEYS_COUNT ; i++) {
|
||||||
if (property_get(variant_keys[i], prop, NULL) == 0) {
|
if (property_get(variant_keys[i], prop, NULL) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
status = load(id, prop, &hmi);
|
snprintf(path, sizeof(path), "%s/%s.%s.so", HAL_LIBRARY_PATH, id, prop);
|
||||||
|
if (access(path, R_OK)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* we found a library matching this id/variant */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try default */
|
status = -ENOENT;
|
||||||
if (status != 0) {
|
if (i < HAL_VARIANT_KEYS_COUNT) {
|
||||||
status = load(id, HAL_DEFAULT_VARIANT, &hmi);
|
/* load the module, if this fails, we're doomed, and we should not try
|
||||||
|
* to load a different variant. */
|
||||||
|
status = load(id, path, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
*module = hmi;
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user