2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <hardware/hardware.h>
30 #define LOG_ERROR " E"
31 #define LOG_DEBUG " D"
32 #define ALOG(pri, tag, fmt, arg...) fprintf(stderr, tag pri": " fmt"\n", ##arg)
34 #define info(fmt, arg...) ALOG(LOG_INFO, LOG_TAG, fmt, ##arg)
35 #define warn(fmt, arg...) ALOG(LOG_WARN, LOG_TAG, fmt, ##arg)
36 #define error(fmt, arg...) ALOG(LOG_ERROR, LOG_TAG, fmt, ##arg)
38 #define HAL_LIBRARY_PATH "/usr/lib"
41 * Load the file defined by the variant and if successful
42 * return the dlopen handle and the hmi.
43 * @return 0 = success, !0 = failure.
45 static int load(const char *id,
47 const struct hw_module_t **pHmi)
51 struct hw_module_t *hmi;
52 const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
55 * load the symbols resolving undefined symbols before
56 * dlopen returns. Since RTLD_GLOBAL is not or'd in with
57 * RTLD_NOW the external symbols will not be global
59 handle = dlopen(path, RTLD_NOW);
61 char const *err_str = dlerror();
62 error("load: module=%s\n%s", path, err_str?err_str:"unknown");
67 /* Get the address of the struct hal_module_info. */
68 hmi = (struct hw_module_t *)dlsym(handle, sym);
70 error("load: couldn't find symbol %s", sym);
75 /* Check that the id matches */
76 if (strcmp(id, hmi->id) != 0) {
77 error("load: id=%s != hmi->id=%s", id, hmi->id);
86 info("loaded HAL id=%s path=%s hmi=%p handle=%p",
87 id, path, *pHmi, handle);
101 int hw_get_module_by_class(const char *class_id, const char *inst,
102 const struct hw_module_t **module)
108 snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
110 snprintf(name, PATH_MAX, "%s", class_id);
113 * Here we rely on the fact that calling dlopen multiple times on
114 * the same .so will simply increment a refcount (and not load
115 * a new copy of the library).
116 * We also assume that dlopen() is thread-safe.
118 snprintf(path, sizeof(path), "%s/%s.default.so", HAL_LIBRARY_PATH, name);
120 return load(class_id, path, module);
123 int hw_get_module(const char *id, const struct hw_module_t **module)
125 return hw_get_module_by_class(id, NULL, module);