diff options
author | Colin Cross <ccross@android.com> | 2013-12-26 13:47:56 -0800 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2014-01-02 13:17:51 -0800 |
commit | 85ab5d1f914f4050309ce81c748ec604ee4f533a (patch) | |
tree | 5da5f75c86185419d06fa0ee290e232ba577bad6 /hardware.c | |
parent | 20ebefd966eed9da545ab645199c2f93ca93af20 (diff) | |
download | hardware_libhardware-85ab5d1f914f4050309ce81c748ec604ee4f533a.zip hardware_libhardware-85ab5d1f914f4050309ce81c748ec604ee4f533a.tar.gz hardware_libhardware-85ab5d1f914f4050309ce81c748ec604ee4f533a.tar.bz2 |
hardware: add ro.hardware.<class> to HAL loading properites list
Try to load a HAL determined by ro.hardware.<class> first before
falling back to hardware, board, platform, arch, and default.
This is intended to be used to support multiple hardware variants
from the same source. For example, a single build that supports
two gps chips, gps001 and gpsb, could use /factory/factory.prop
to set ro.hardware.gps=gps001 or ro.hardware.gps=gpsb, which would
load gps.gps001.so or gps.gpsb.so. Two separate builds from the
same source could use PRODUCT_PROPERTY_OVERRIDES to set the
properties.
Change-Id: I1ac46c21ceb27ceb5165e8c44e9373e9c5d4e34e
Diffstat (limited to 'hardware.c')
-rw-r--r-- | hardware.c | 72 |
1 files changed, 44 insertions, 28 deletions
@@ -117,15 +117,34 @@ static int load(const char *id, return status; } +/* + * Check if a HAL with given name and subname exists, if so return 0, otherwise + * otherwise return negative. On success path will contain the path to the HAL. + */ +static int hw_module_exists(char *path, size_t path_len, const char *name, + const char *subname) +{ + snprintf(path, path_len, "%s/%s.%s.so", + HAL_LIBRARY_PATH2, name, subname); + if (access(path, R_OK) == 0) + return 0; + + snprintf(path, path_len, "%s/%s.%s.so", + HAL_LIBRARY_PATH1, name, subname); + if (access(path, R_OK) == 0) + return 0; + + return -ENOENT; +} + int hw_get_module_by_class(const char *class_id, const char *inst, const struct hw_module_t **module) { - int status; int i; - const struct hw_module_t *hmi = NULL; char prop[PATH_MAX]; char path[PATH_MAX]; char name[PATH_MAX]; + char prop_name[PATH_MAX]; if (inst) snprintf(name, PATH_MAX, "%s.%s", class_id, inst); @@ -139,38 +158,35 @@ int hw_get_module_by_class(const char *class_id, const char *inst, * We also assume that dlopen() is thread-safe. */ + /* First try a property specific to the class and possibly instance */ + snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name); + if (property_get(prop_name, prop, NULL) == 0) { + if (hw_module_exists(path, sizeof(path), name, prop) == 0) { + goto found; + } + } + /* Loop through the configuration variants looking for a module */ - for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) { - if (i < HAL_VARIANT_KEYS_COUNT) { - if (property_get(variant_keys[i], prop, NULL) == 0) { - continue; - } - snprintf(path, sizeof(path), "%s/%s.%s.so", - HAL_LIBRARY_PATH2, name, prop); - if (access(path, R_OK) == 0) break; - - snprintf(path, sizeof(path), "%s/%s.%s.so", - HAL_LIBRARY_PATH1, name, prop); - if (access(path, R_OK) == 0) break; - } else { - snprintf(path, sizeof(path), "%s/%s.default.so", - HAL_LIBRARY_PATH2, name); - if (access(path, R_OK) == 0) break; - - snprintf(path, sizeof(path), "%s/%s.default.so", - HAL_LIBRARY_PATH1, name); - if (access(path, R_OK) == 0) break; + for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) { + if (property_get(variant_keys[i], prop, NULL) == 0) { + continue; + } + if (hw_module_exists(path, sizeof(path), name, prop) == 0) { + goto found; } } - status = -ENOENT; - if (i < HAL_VARIANT_KEYS_COUNT+1) { - /* load the module, if this fails, we're doomed, and we should not try - * to load a different variant. */ - status = load(class_id, path, module); + /* Nothing found, try the default */ + if (hw_module_exists(path, sizeof(path), name, "default") == 0) { + goto found; } - return status; + return -ENOENT; + +found: + /* load the module, if this fails, we're doomed, and we should not try + * to load a different variant. */ + return load(class_id, path, module); } int hw_get_module(const char *id, const struct hw_module_t **module) |