深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一

来源:互联网 发布:怎么在淘宝上买东西啊 编辑:程序博客网 时间:2024/05/14 15:07

    最近看Sensor差点没看吐了~~~ 有个东东老是没有看明白,在网上看到两个高手写得文章在这转载。经过全部代码的走读应该没有问题!

======================================================原文==================================================================

1.      Sensor的概念

Sensor即传感器,在当前智能手机上大量存在:G-Sensor、LightsSensor、ProximitySensor、TemperatureSensor等,其作为Android系统的一个输入设备,对于重视用户体验的移动设备来说是必不可少的。Sensor虽然是一个输入设备,但是它又不同于触摸屏,键盘,按键等这些常规的输入设备,因为Sensor的数据输入从传感器硬件到设备的,而常规的输入设备是从用户到设备的,比如:温度传感器用于感知温度的变化,采样传感器数据上报给设备。而传感器硬件的工作与否,采样精度是由用户来控制的,所以对应Sensor而言是其工作方式是双向的,即:控制硬件的控制流,硬件上报的数据流。这也决定了Sensor的框架不同与触摸屏等常规输入子系统。

本章节主要研究的Sensor框架代码与SensorHAL的实现细节,一切还是从Sensor框架开始,首先来回顾下Led HAL的实现框架。


Led HAL是我们自己实现的,主要分为四部分:

Led App:Led的应用程序

Led Service框架:Led应用的API提供者

LedService本地:LedService服务的本地实现,上层与底层的通信转化接口

Led HAL Stub:HAL层代码,具体硬件驱动操作接口

很明显,我们写的Led HAL代码是典型的控制流,反馈结果就是Led灯的亮与灭,它的架构不适用于Sensor架构,具体有如下几点:

l  Led是单纯的控制流,而Sensor是控制流与数据流

Sensor的数据流不是实时的,而是有采样速率,并且数据不是连续的,阻塞在读取硬件设备数据上,只有数据得到才返回。

l  Sensor是提供给所有传感器的通用框架,不是针对某一特定硬件的架构

Sensor包含多种类型,在上层和底层都有对Sensor具体类型的屏蔽,让它通用所有传感器。

l  Sensor的服务不是由应用程序创建启动的,应该是伴随系统启动的

任何一个应用程序里都可以使用Sensor服务,这决定了Sensor服务应该伴随系统启动。

 

2.      Sensor的框架分析

本节是本系列第一个分析的具体设备的框架,从Android SensorService的注册启动开始,到应用程序获得SensorManager注册传感器监听器,详细分析从应用层到Java框架层再到本地代码,最后调用HAL层全部过程。

1.1  Sensor服务的启动

由前面Android启动流程章节可知,Zygote启动起来后,运行的每一个Java进程是SystemServer,它用来启动并管理所有的Android服务:

[cpp] view plaincopy
  1. public static void main(String[] args) {  
  2.     …  
  3.        System.loadLibrary("android_servers");  
  4.        init1(args);  
  5.       }  

由SystemServer的main方法可知,其加载了libandroid_servers.so的库,并且调用了init1()方法。

我们通过下面的命令来找到该库的编译目录:

[plain] view plaincopy
  1. find ./frameworks/base –name Android.mk –exec grep –l libandroid_servers{}\;  

通过打印的信息知道,其对应的源码目录在:frameworks/base/services/jni/下,其实Android框架层的代码的特点就是Java目录下存放的是对应的Java框架代码,对应的jni目录下是对应的本地代码。

在这个目录所有的代码最重要的就是:com_android_server_SystemServer.cpp:

[cpp] view plaincopy
  1. namespace android {  
  2.   
  3. extern "C" int system_init();  
  4. static void android_server_SystemServer_init1(JNIEnv*env, jobject clazz)  
  5. {  
  6.    system_init();  
  7. }  
  8. /* 
  9.  * JNIregistration. 
  10.  */  
  11. static JNINativeMethod gMethods[] = {  
  12.     /* name,signature, funcPtr */  
  13.     {"init1""([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1},  
  14. };  
  15.   
  16. int register_android_server_SystemServer(JNIEnv* env)  
  17. {  
  18.     returnjniRegisterNativeMethods(env, "com/android/server/SystemServer",  
  19.            gMethods, NELEM(gMethods));  
  20. }  
  21.   
  22. }; // namespace android  

代码不是很多,也比较好读,调用jniRegisterNativeMethods方法注册SystemServer的Java方法也本地方法映射关系,jniRegisterNativeMethods是一个本地方法的注册Helper方法。

SystemServer.java在加载了libandroid_servers.so库之后,调用了init1(),通过上面代码中的映射关系可知,它调用了本地的android_server_SystemServer_init1方法,该方法直接调用system_init(),其实现在frameworks/base/cmds/system_server/library/system_init.cpp中实现:

[cpp] view plaincopy
  1. extern "C" status_t system_init()  
  2. {  
  3.    LOGI("Entered system_init()");  
  4.    sp<ProcessState> proc(ProcessState::self());  
  5.    sp<IServiceManager> sm = defaultServiceManager();  
  6.    LOGI("ServiceManager: %p\n", sm.get());  
  7.    sp<GrimReaper> grim = new GrimReaper();  
  8.    sm->asBinder()->linkToDeath(grim, grim.get(), 0);  
  9.   
  10.     charpropBuf[PROPERTY_VALUE_MAX];  
  11.    property_get("system_init.startsurfaceflinger", propBuf,"1");  
  12.     if(strcmp(propBuf, "1") == 0) {  
  13.         // Startthe SurfaceFlinger  
  14.        SurfaceFlinger::instantiate();  
  15.     }  
  16.   
  17.     property_get("system_init.startsensorservice", propBuf,"1");  
  18.     if(strcmp(propBuf, "1") == 0) {  
  19.         // Startthe sensor service  
  20.        SensorService::instantiate();  
  21.     }  
  22.     LOGI("Systemserver: starting Android runtime.\n");  
  23.    AndroidRuntime* runtime = AndroidRuntime::getRuntime();  
  24.   
  25.    LOGI("System server: starting Android services.\n");  
  26.     JNIEnv* env =runtime->getJNIEnv();  
  27.     if (env ==NULL) {  
  28.         returnUNKNOWN_ERROR;  
  29.     }  
  30.   
  31.     jclass clazz= env->FindClass("com/android/server/SystemServer");  
  32.     if (clazz ==NULL) {  
  33.         returnUNKNOWN_ERROR;  
  34.     }  
  35.   
  36.     jmethodIDmethodId = env->GetStaticMethodID(clazz, "init2","()V");  
  37.     if (methodId== NULL) {  
  38.         returnUNKNOWN_ERROR;  
  39.     }  
  40.    env->CallStaticVoidMethod(clazz, methodId);  
  41.   
  42.     LOGI("System server: entering thread pool.\n");  
  43.    ProcessState::self()->startThreadPool();  
  44.    IPCThreadState::self()->joinThreadPool();  
  45.    LOGI("System server: exiting thread pool.\n");  
  46. }  

如果了解Binder机制的话,应该知道,sp<ProcessState> proc(ProcessState::self())打开Binder驱动并会创建一个ProcessState对象并维持当前进程的Binder通信的服务器端。

如果系统属性里配置了system_init.startsensorservice 属性为1,则通过SensorService::instantiate()启动Sensor服务。

对于初学者最头疼的就是追面向对象代码中的重载,重写的代码了,SensorService::instantiate()调用的是其父类的方法,我们可以通过子类的定义找其继承关系,然后顺着继承关系再来查找方法的实现,如果在子类里和父类里都有方法的实现,那么看参数的匹配,如果参数都相互匹配,那么就是所谓的重写,调用的是子类的方法。SensorService的定义如下:

@frameworks/base/services/sensorservice/SensroService.h

[cpp] view plaincopy
  1. class SensorService :  
  2.         publicBinderService<SensorService>,  
  3.         publicBnSensorServer,  
  4.         protectedThread  
  5. {  

通过SensorService的定义可知,在当前类里没有instantiate方法的声明,说明其调用的是父类的方法,其继承了BinderService,BnSensorServer,Thread类(难道SensorService是一个线程??),顺着继承关系找,在BinderService里可以找到instantiate方法的声明。

@frameworks/base/include/binder/BinderService.h

[cpp] view plaincopy
  1. template<typename SERVICE>  
  2.   
  3. class BinderService  
  4. {  
  5. public:  
  6.     static status_t publish() {  
  7.        sp<IServiceManager> sm(defaultServiceManager());  
  8.        returnsm->addService(String16(SERVICE::getServiceName()), new SERVICE());  
  9.     }  
  10.   
  11.     static void publishAndJoinThreadPool() {  
  12.        sp<ProcessState> proc(ProcessState::self());  
  13.        sp<IServiceManager> sm(defaultServiceManager());  
  14.        sm->addService(String16(SERVICE::getServiceName()), new SERVICE());  
  15.        ProcessState::self()->startThreadPool();  
  16.        IPCThreadState::self()->joinThreadPool();  
  17.     }  
  18.   
  19.     static void instantiate() { publish(); }  
  20.   
  21.     static status_t shutdown() {  
  22.         return NO_ERROR;  
  23.     }  
  24. };  

通过上面代码分析可知,instantiate方法创建了SensorService并通过addService将自己新创建的SensorService服务添加到Android服务列表里了。

Ok,那我们来到SensorService服务中。

@frameworks/base/services/sensorservice/SensorService.cpp

[cpp] view plaincopy
  1. SensorService::SensorService()  
  2.     :mInitCheck(NO_INIT)  
  3. {  
  4. }  
  5.   
  6. void SensorService::onFirstRef()  
  7. {  
  8.    LOGD("nuSensorService starting...");  
  9.    SensorDevice& dev(SensorDevice::getInstance());  
  10. …  

SensorService的构造方法比较简单,初始化了成员变量mInitCheck为NO_INIT。

要注意构造方法后面的onFirstRef方法,它是Android系统里引用计数系统里的一个方法。当RefBase的子类对象被第一次强引用时自动调用其方法,所以当第一次使用SensorService服务里该方法被自动回调。

形如:

[cpp] view plaincopy
  1. sp< ISensorServer> sm(mSensorService);  

注:关于引用计数系统,如果读者不太了解,请参考邓凡平老师的:深入理解:Android系统核心 卷I中的三板斧部分。

SensorService的启动到此暂停,等待上层应用的使用SensorService服务并调用onFirstRef方法。

来源:http://blog.csdn.net/mr_raptor/article/details/8090474