CameraService.cpp (frameworks\base\services\camera\libcameraservice)
中调用hw_get_module - void CameraService::onFirstRef()
- {
- BnCameraService::onFirstRef();
-
- <span style="color:#ff0000;">if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
- (const hw_module_t **)&mModule) < 0)</span> {
- LOGE("Could not load camera HAL module");
- mNumberOfCameras = 0;
- }
- else {
- mNumberOfCameras = mModule->get_number_of_cameras();
- if (mNumberOfCameras > MAX_CAMERAS) {
- LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
- mNumberOfCameras, MAX_CAMERAS);
- mNumberOfCameras = MAX_CAMERAS;
- }
- for (int i = 0; i < mNumberOfCameras; i++) {
- setCameraFree(i);
- }
- }
- }
看一下hw_get_module是怎么回事
- int hw_get_module(const char *id, const struct hw_module_t **module)
- {
- return <span style="color:#ff0000;">hw_get_module_by_class(id, NULL, module);
- </span>}
他只是一个封装实际调用了hw_get_module_by_class@Hardware.c (hardware\libhardware) 好在不长,看看吧 - 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;
- <span style="color:#ff0000;"> char prop[PATH_MAX];
- char path[PATH_MAX];
- char name[PATH_MAX];
- </span>
- if (inst)
- snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
- else
- strlcpy(name, class_id, PATH_MAX);
-
-
-
-
-
-
-
-
-
- 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)
- <span style="color:#ff0000;">
- "ro.hardware[qcom]"
- "ro.product.board"[7x27],
- "ro.board.platform"[msm7627a],
- "ro.arch",
- "ro.hw_platform"[QRD_SKU3-1100]
- 这几个属性文件中获得硬件的信息
- 有些硬件信息的字符串会出现在编译后生成的.so名字中</span>
- {
- 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);<span style="color:#ff0000;">
- 这样一个路径,这个库里有QualcommCamera.cpp,这是
- camera模块HAL代码开始的地方</span>
- if (access(path, R_OK) == 0) break;
- } else {
- snprintf(path, sizeof(path), "%s/%s.default.so",
- HAL_LIBRARY_PATH1, name);
- if (access(path, R_OK) == 0) break;
- }
- }
-
- status = -ENOENT;
- if (i < HAL_VARIANT_KEYS_COUNT+1) {
-
-
- status = load(class_id, path, module);<span style="color:#ff0000;">
- 到path(/system/lib/hw/camera.msm7627a.so)这个路径下找到一个id(camera)匹配的module</span>
- }
-
- return status;
- }
再来看看load这个函数@hardware.c (hardware\libhardware)- static int load(const char *id,
- const char *path,
- const struct hw_module_t **pHmi)
- {
- int status;
- void *handle;
- struct hw_module_t *hmi;
-
-
-
-
-
-
- handle = dlopen(path, RTLD_NOW);
- if (handle == NULL) {
- char const *err_str = dlerror();
- LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
- status = -EINVAL;
- goto done;
- }
-
- <span style="color:#ff0000;">
- const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
- hmi = (struct hw_module_t *)dlsym(handle, sym);
- </span> if (hmi == NULL) {
- LOGE("load: couldn't find symbol %s", sym);
- status = -EINVAL;
- goto done;
- }
-
-
- if (strcmp(id, hmi->id) != 0) {
- LOGE("load: id=%s != hmi->id=%s", id, hmi->id);
- status = -EINVAL;
- goto done;
- }
-
- hmi->dso = handle;
-
-
- status = 0;
-
- done:
- if (status != 0) {
- hmi = NULL;
- if (handle != NULL) {
- dlclose(handle);
- handle = NULL;
- }
- } else {
- LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
- id, path, *pHmi, handle);
- }
-
- *pHmi = hmi;
-
- return status;
- }
在打开的.so(camera.msm7627a.so)中查找HMI符号的地址,并保存在hmi中。至此,.so中的hw_module_t已经被成功获取,从而可以根 据它获取别的相关接口。 1)HAL通过hw_get_module函数获取hw_module_t 2)HAL通过hw_module_t->methods->open获取hw_device_t指针,并在此open函数中初始化hw_device_t的包装结构中的 函数及hw_device_t中的close函数,如gralloc_device_open。 3)三个重要的数据结构: a) struct hw_device_t: 表示硬件设备,存储了各种硬件设备的公共属性和方法 b)struct hw_module_t: 可用hw_get_module进行加载的module c)struct hw_module_methods_t: 用于定义操作设备的方法,其中只定义了一个打开设备的方法open.
|