summaryrefslogtreecommitdiffstats
path: root/hardware.c
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2013-12-26 13:47:56 -0800
committerColin Cross <ccross@android.com>2014-01-02 13:17:51 -0800
commit85ab5d1f914f4050309ce81c748ec604ee4f533a (patch)
tree5da5f75c86185419d06fa0ee290e232ba577bad6 /hardware.c
parent20ebefd966eed9da545ab645199c2f93ca93af20 (diff)
downloadhardware_libhardware-85ab5d1f914f4050309ce81c748ec604ee4f533a.tar.gz
hardware_libhardware-85ab5d1f914f4050309ce81c748ec604ee4f533a.tar.bz2
hardware_libhardware-85ab5d1f914f4050309ce81c748ec604ee4f533a.zip
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.c72
1 files changed, 44 insertions, 28 deletions
diff --git a/hardware.c b/hardware.c
index 9651f4c..da89dd9 100644
--- a/hardware.c
+++ b/hardware.c
@@ -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)