深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一
作者:唐老师,华清远见嵌入式学院讲师。
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 plaincopyprint?
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 plaincopyprint?
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 plaincopyprint?
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 plaincopyprint?
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 proc(ProcessState::self())打开Binder驱动并会创建一个ProcessState对象并维持当前进程的Binder通信的服务器端。
如果系统属性里配置了system_init.startsensorservice 属性为1,则通过SensorService::instantiate()启动Sensor服务。
对于初学者最头疼的就是追面向对象代码中的重载,重写的代码 了,SensorService::instantiate()调用的是其父类的方法,我们可以通过子类的定义找其继承关系,然后顺着继承关系再来查找方 法的实现,如果在子类里和父类里都有方法的实现,那么看参数的匹配,如果参数都相互匹配,那么就是所谓的重写,调用的是子类的方法。 SensorService的定义如下:
@frameworks/base/services/sensorservice/SensroService.h
[cpp] view plaincopyprint?
1. class
SensorService :
2.
publicBinderService,
3.
publicBnSensorServer,
4.
protectedThread
5. {
通过SensorService的定义可知,在当前类里没有instantiate方法的声明,说明其调用 的是父类的方法,其继承了BinderService,BnSensorServer,Thread类(难道SensorService是一个线 程??),顺着继承关系找,在BinderService里可以找到instantiate方法的声明。
@frameworks/base/include/binder/BinderService.h
[cpp] view plaincopyprint?
1. template
2.
3. class BinderService
4. {
5. public:
6. static status_t
publish() {
7. sp
sm(defaultServiceManager());
8.
returnsm->addService(String16(SERVICE::getServiceName()), new SERVICE());
9. }
10.
11. static void
publishAndJoinThreadPool() {
12. sp
proc(ProcessState::self());
13. sp
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 plaincopyprint?
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 plaincopyprint?
1. sp< ISensorServer> sm(mSensorService);
注:关于引用计数系统,如果读者不太了解,请参考邓凡平老师的:深入理解:Android系统核心 卷I中的三板斧部分。
SensorService的启动到此暂停,等待上层应用的使用SensorService服务并调用onFirstRef方法。
文章来源:华清远见嵌入式学院,原文地址:http://www.embedu.org/Column/Column770.htm
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。