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)
39 #define HAL_LIBRARY_PATH "/usr/lib64"
41 #define HAL_LIBRARY_PATH "/usr/lib"
45 * Load the file defined by the variant and if successful
46 * return the dlopen handle and the hmi.
47 * @return 0 = success, !0 = failure.
49 static int load(const char *id,
51 const struct hw_module_t **pHmi)
55 struct hw_module_t *hmi;
56 const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
59 * load the symbols resolving undefined symbols before
60 * dlopen returns. Since RTLD_GLOBAL is not or'd in with
61 * RTLD_NOW the external symbols will not be global
63 handle = dlopen(path, RTLD_NOW);
65 char const *err_str = dlerror();
66 error("load: module=%s\n%s", path, err_str ? err_str : "unknown");
71 /* Get the address of the struct hal_module_info. */
72 hmi = (struct hw_module_t *)dlsym(handle, sym);
74 error("load: couldn't find symbol %s", sym);
79 /* Check that the id matches */
80 if (strcmp(id, hmi->id) != 0) {
81 error("load: id=%s != hmi->id=%s", id, hmi->id);
90 info("loaded HAL id=%s path=%s hmi=%p handle=%p",
91 id, path, *pHmi, handle);
105 int hw_get_module_by_class(const char *class_id, const char *inst,
106 const struct hw_module_t **module)
112 snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
114 snprintf(name, PATH_MAX, "%s", class_id);
117 * Here we rely on the fact that calling dlopen multiple times on
118 * the same .so will simply increment a refcount (and not load
119 * a new copy of the library).
120 * We also assume that dlopen() is thread-safe.
122 snprintf(path, sizeof(path), "%s/%s.default.so", HAL_LIBRARY_PATH, name);
124 return load(class_id, path, module);
127 int hw_get_module(const char *id, const struct hw_module_t **module)
129 return hw_get_module_by_class(id, NULL, module);