本文基于android系统源码情景分析-罗升阳
kernel driver
kernel/driver
----freg
----freg.h
----freg.c
----Konfig
----Makefile
----Kconfig
----Makefile
#kernel/driver/freg/Konfig #使得make menuconfig可以选择是否编译进内核或者编译成模块 congfig FREG tristate "Fake Register Driver" default n help This is the freg driver for android system.
#kernel/driver/freg/Makefile obj-$(CONFIG_FREG) += freg.o
#kernel/driver/Konfig menu "Device Drivers" source "drivers/freg/Konfig" ...... endmenu
#kernel/driver/Makefile obj-$(CONFIG_FREG) += freg/
HAL
Android系统中HAL模块由系统统一加载。当调用者需要使用这些模块时指定id就行。
int hw_get_module(const char *id, const struct hw_module_t **module);
编译好的模块位于out/target/product/generic/system/lib/hw.经过打包后位于设备的/system/lib/hw或vendor/lib/hw下。
Android/hardware/libhardware
----include
----hardware/libhardware----freg.h
----modules
----freg
----freg.cpp
----Android.mk
Frameworks
frameworks/base/core/java/android/os/IFregServer.aidl
frameworks/base/services/java/com/android/server/FregServer.java
frameworks/base/services/jni/com_android_service_FregServer.cpp
#frameworks/base/services/java/com/android/server/SystemService.java
AIDL
Android APP直接通过Service(service extend AIDL.Stub)调用.so格式的JNI。
标准方法:APP经过Manager(在framework层通过ServiceManager得到具体的Service)调用Service。
Android标准方式APP和manager为一体,manager和service之间也利用AIDL进行通信。
Android系统的硬件访问服务运行在系统进程System中,而需要使用硬件访问服务的APP运行在另外进程。定义硬件访问服务接口,使得APP可以调用。mmm./frameworks/base/ 编译后得到framework.jar包含IFregServer接口。IFregServer.aild被转换为java程序。IFregServer继承android.os.IInterface接口, IFregServer内部定义了一个Binder本地对象类Stub,它实现了IFregServer接口(setval, getval)。IFregServer.Stub类内部定义了一个Binder代理对象类Proxy,它也实现了IFregServer接口。
每个服务都对应一个Binder本地对象,它通过Stub来等待Client进程发送进程间通信请求。Client进程首先获得Server的一个Binder代理对象连接口Proxy,通过Proxy发送通信请求。
frameworks/base/
----core/java/android/os/
----IFregServer.aidl
----Android.mk #在LOACL_SRC_FILES中加入IFregServer.aidl
FregServer.java
APP通过AIDL调用FregServer.jar(应用层调用时只需要ServiceManager.getService("freg"), 然后再调用其中的setVal()和getVal() ),FregServer.java再调用jniframeworks/base/services/java/com/android/server/FregServer.java
#frameworks/base/services/java/com/android/server/FregServer.java public class FregService extends IFregService.Stub{ private int mPtr = 0;//表示是否初始化成功 FregService(){ mPtr = init_native; ...... } public void setVal(int val){ setVal_native(mPtr, val); } public int getVal(int val){ return getVal_native(mPtr); } private static native int init_native(); private static native void setVal_native(int ptr, int val); private static native int getVal_native(int ptr); }
JNI
jni调用HAL。mmm ./frameworks/base/services/jni/重写编译后得到libandroid_servers.so就包含init_native, setVal_native, getVal_native。
frameworks/base/services/jni/
----com_android_service_FregServer.cpp
----onload.cpp
----Android.mk
#frameworks/base/services/jni/com_android_service_FregServer.cpp namespace android{ static void freg_setVal(JNIEnv* env, jobject clazz, jint ptr, int vale){ ...... device->set_val(device, val); } static jint freg_getVal(JNIEnv* env, jobject clazz, jint ptr){ ...... } static inline int freg_device_open(const hw_module_t* module, struct freg_device_t** device){ return module->methods->open(module, FREG_HARDWARE_DEVICE_ID, (struct hw_device_t**)device); } static jint freg_init(JNIEnv* env, jobject clazz){ hw_get_module(FREG_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module){ ...... freg_device_open(&(module->commom), &device); } } static const JNINativeMethod method_table[] = { {"init_native", "()I", (void*)freg_init}, {"setVal_native", "(II)V", (void*)freg_setVal}, {"getVal_native", "(I)I", (void*)freg_getVal} }; int register_android_server_FregServer(JNIEnv *env){ return jniRegisterNativeMethods(env, "com/android/server/FregService", method_table, NELEM(method_table)); } } #frameworks/base/services/jni/onload.cpp namespace android{ ...... int register_android_server_FregServer(JNIEnv *env); }; using namespace android; extern "C" jint JIN_OnLoad(JavaVM* vm, void* reserved){ ...... register_android_server_FregServer(env); return JNI_VERSION_1_4; }
启动硬件访问服务
#frameworks/base/services/java/com/android/server/SystemService.java
#frameworks/base/services/java/com/android/server/SystemService.java class ServerThread extends Thread{ public void run(){ ...... ServiceManager.addService("freg", new FregService()); }