HAL需要实现的核心数据结构
rootdir/hardware/libhardware/include/hardware/hardware.h
struct hw_module_t;
struct hw_module_methods_t;
struct hw_device_t;
typedef structhw_module_t {
uint32_ttag;
uint16_tmodule_api_version;
#define version_major module_api_version
uint16_t hal_api_version;
#define version_minor hal_api_version
/** Identifier of module */
const char *id;
/** Name of this module */
const char *name;
/** Author/owner/implementor of the module */
const char *author;
/** Modules methods */
struct hw_module_methods_t* methods;
/** module's dso */
void* dso;
#ifdef __LP64__
uint64_t reserved[32-7];
#else
/** padding to 128 bytes, reserved for future use */
uint32_t reserved[32-7];
#endif
} hw_module_t;
typedef structhw_module_methods_t {
/** Open a specific device */
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);
} hw_module_methods_t;
typedef structhw_device_t {
uint32_t tag;
uint32_t version;
struct hw_module_t* module;
#ifdef __LP64__
uint64_t reserved[12];
#else
uint32_t reserved[12];
#endif
int (*close)(struct hw_device_t* device);
} hw_device_t;
具体实现过程中,会继承以上三个数据结构,实现模块特定的功能
如何注册以及调用HAL层
Hal层实现上面数据结构后,会编译生成.so放在/system/lib64/hw、vendor/lib64/hw或者/odm/lib/hw目录下,当App有需要时依如下流程加载调用
app -> javaService -> jniService-> hal(.so)->drv
TranHello调用过程
App
App启动时通过ServiceManager获取服务HelloService
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
helloService =IHelloService.Stub.asInterface(
ServiceManager.getService("hello"));
......
}
Framwork Java Service
HelloService实例化
public HelloService() {
Slog.v(TAG,"HelloService");
init_native();
}
实例化时候会调用init_native()函数,改函数在Framwork Jni Service实现
Framwork Jni Service
开机的时候init_native()函数会被注册到JVM
int register_android_server_HelloService(JNIEnv *env) {
return jniRegisterNativeMethods(env, "com/android/server/hello/HelloService",method_table, NELEM(method_table));
}
extern "C" jintJNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
......
register_android_server_HelloService(env);
returnJNI_VERSION_1_4;
}
init_native函数签名
static const JNINativeMethod method_table[] = {
{"init_native", "()Z",(void*)hello_init},
{"setVal_native", "(I)V", (void*)hello_setVal},
{"getVal_native", "()I", (void*)hello_getVal},
};
最终会调到hello_init函数
static jboolean hello_init(JNIEnv* env,jclass clazz) {
hello_module_t* module;
if(
hw_get_module(HELLO_HARDWARE_MODULE_ID,
(const struct hw_module_t**)&module)== 0
){
ALOGE("Hello JNI: hello Stub found.");
if(hello_device_open(&(module->common),&hello_device) == 0) {
ALOGE("Hello JNI: hellodevice is open.");
return 0;
}
ALOGE("Hello JNI: failed to open hello device.");
return -1;
}
ALOGE("Hello JNI: failed to get hello stub module.");
return -1;
}
hello_init函数首先会调用hw_get_module加载hello.mt6763.so得到操作so的对象hw_module_t对象HMI
【关于hw_get_module函数的实现原理可参考[3] hello_framworks_jni_test_ok/JNI.docx】
hello_init接着会调用hello_device_open函数得到hello_device
static inline int hello_device_open(const hw_module_t* module, structhello_device_t** device) {
return module->methods->open(module, HELLO_HARDWARE_MODULE_ID, (structhw_device_t**)device);
}
hello_init函数执行完成之后会得到一个初始化好的hello_device_t对象,之后JNI层的所有操作都是通过这个hello_device_t完成的
Hal Interface
/*模块方法表*/
static struct hw_module_methods_thello_module_methods = {
open: hello_device_open
};
/*模块实例变量*/
struct hello_module_t HAL_MODULE_INFO_SYM ={
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: HELLO_HARDWARE_MODULE_ID,
name: MODULE_NAME,
author: MODULE_AUTHOR,
methods: &hello_module_methods,
}
};
//hello_device_open
/***************************************************************************************************************************************************/
static int hello_device_open(const structhw_module_t* module, const char* name, struct hw_device_t** device) {
struct hello_device_t* dev;
dev = (struct hello_device_t*)malloc(sizeof(struct hello_device_t));
ALOGE("Hello Stub: hello_device_open start");
if(!dev) {
ALOGE("Hello Stub: failed to alloc space");
return -EFAULT;
}
memset(dev, 0, sizeof(struct hello_device_t));
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = 0;
dev->common.module = (hw_module_t*)module;
dev->common.close = hello_device_close;
dev->set_val = hello_set_val;dev->get_val = hello_get_val;
if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {
ALOGE("Hello Stub: failed to open /dev/hello -- %s.",strerror(errno));free(dev);
return -EFAULT;
}
*device = &(dev->common);
ALOGE("Hello Stub: open /dev/hello successfully.");
return 0;
}
最终到hello_device_open完成之后就将hello模块的所有操作方法注册到hello_device对象并返回给Framwork Jni Service,Framwork Jni Service在通过JNI简介呈现给Framwork Java Service的HelloService,最终App就可以通过HelloService操作整个hello模块了
总结
当App onCreate时,通过ServiceManager获取Framwork Java Service的时候,实际上会实例化一个Service,在Service实例化过程中,实际上是会通过JNI规则在JNI层通过hw_get_module函数调用load函数加载对应的so获取到对应的hw_module_t对象,进而通过hw_module_methods_t对象的open接口将模块的操作方法加载到hw_device_t对象中返回给JNI层,JNI层通过hw_device_t的子类对象实现模块的各种操作方法,并并通过JNI_Onload函数注册到JVM中,以满足Framwork Java Service的调用,Framwork Java Service需要实现AIDL接口中定义的方法,在这些方法中通过JNI调用Framwork Jni Service封装的各种操作方法
Hal层数据结构
hw_get_module() -> hw_module_t ->hw_module_method_t -> open -> hw_device_t
jni实现
staticvoid hello_setVal(JNIEnv* env, jobject clazz, jint value) {
int val = value;
if(!hello_device) {
return;
}
hello_device->set_val(hello_device,val);
}
static jint hello_getVal(JNIEnv* env, jobject clazz) {
int val = 0;
if(!hello_device) {
return val;
}
hello_device->get_val(hello_device,&val);
return val;
}