前言
这一章,我们将从 hw_get_module() 函数入手,去探究 Libraries 层是如何调用 HAL 层的库中的函数的。
CameraService 是在开机时就会启动的,而当它第一次启动时,就会调用一个名为 onFirstRef() 的成员函数,我们所要探究的内容就是从这里开始的。
1 CameraService
- 路径:
framework/av/services/camera/libcameraservice/CameraService.cpp CameraService::onFirstRef():- 首先调用其基类的
onFirstRef函数。 - 更新
notifier(这个BatteryNotifier好像是个单例,看类名好像和电池有关)。 - 通过
hw_get_module函数获取rawModule。 - 注意
rawModule是camera_module_t类型。 - 利用
rawModule创建mModule的实例,mModule是CameraModule类。
- 首先调用其基类的
BnCameraService::onFirstRef();
// Update battery life tracking if service is restarting
BatteryNotifier& notifier(BatteryNotifier::getInstance());
notifier.noteResetCamera();
notifier.noteResetFlashlight();
camera_module_t *rawModule;
/*** NOTE THIS ***/
int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(const hw_module_t **)&rawModule);
if (err < 0) {
ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
logServiceError("Could not load camera HAL module", err);
return;
}
/*** NOTE THIS ***/
mModule = new CameraModule(rawModule);
err = mModule->init();
2 hardware
2.1 hardware.h
- 路径:
hardware/libhardware/include/hardware/hardware.h - 注意两个宏定义:
/**
* Name of the hal_module_info
*/
#define HAL_MODULE_INFO_SYM HMI
/**
* Name of the hal_module_info as a string
*/
#define HAL_MODULE_INFO_SYM_AS_STR "HMI"
声明了这两个函数:
hw_get_module():- 作用是通过传入的
id来获取模块相关的信息。 - 成功则返回
0,出错则返回值小于0且*module == NULL。
- 作用是通过传入的
hw_get_module_by_class():- 作用是通过
class_id获取与模块实例相关的信息。 - 提供模块信息的库文件应该是带有这样命名规范的:
- 作用是通过
audio.primary.<variant>.soaudio.a2dp.<variant>.so
/**
* Get the module info associated with a module by id.
*
* @return: 0 == success, <0 == error and *module == NULL
*/
int hw_get_module(const char *id, const struct hw_module_t **module);
/**
* Get the module info associated with a module instance by class 'class_id'
* and instance 'inst'.
*
* Some modules types necessitate multiple instances. For example audio supports
* multiple concurrent interfaces and thus 'audio' is the module class
* and 'primary' or 'a2dp' are module interfaces. This implies that the files
* providing these modules would be named audio.primary.<variant>.so and
* audio.a2dp.<variant>.so
*
* @return: 0 == success, <0 == error and *module == NULL
*/
int hw_get_module_by_class(const char *class_id, const char *inst,
const struct hw_module_t **module);
2.2 hardware.c
- 路径:
hardware/libhardware/hardware.c - 注意这个数组:
static const char *variant_keys[] = {
"ro.hardware", /* This goes first so that it can pick up a different
file on the emulator. */
"ro.product.board",
"ro.board.platform",
"ro.arch"
};
hw_get_module():- 这是我们重点追踪的函数。
- 它直接返回调用另一个函数。
int hw_get_module(const char *id, const struct hw_module_t **module)
{
return hw_get_module_by_class(id, NULL, module);
}
hw_get_module_by_class():- 读取库文件,尝试的顺序是:
ro.hardwarero.product.boardro.board.platformro.archdefault
- 通过
load函数加载模块。
- 读取库文件,尝试的顺序是:
/* First try a property specific to the class and possibly instance */<

本文详细探讨了Android系统中Libraries层如何通过hw_get_module()函数调用HAL层的函数。从CameraService的onFirstRef()开始,介绍了BatteryNotifier的更新,接着深入到硬件接口的hw_get_module()和hw_get_module_by_class(),解析了它们如何根据设备配置加载相应的硬件模块。随后,通过dlopen()和dlsym()函数获取动态链接库中的结构体,实现HAL层的入口。最后,展示了CameraModule的构造和初始化过程,以及不同层级的函数指针映射。整个过程揭示了Android系统内部模块间通信的底层机制。
最低0.47元/天 解锁文章
798

被折叠的 条评论
为什么被折叠?



