From: http://blog.csdn.net/mr_raptor/article/details/8090474
1. Concept of Sensor
Sensor, a sensor, is a large number of existing smart phones, such as G-sensor, lightssensor, proximitysensor, and temperaturesensor. It is used as an input device of the Android system, it is essential for mobile devices that focus on user experience. Although the sensor is an input device, it is different from conventional input devices such as touch screens, keyboards, and buttons, because the data input from the sensor hardware to the device, the conventional input device is from the user to the device. For example, a temperature sensor is used to detect temperature changes and sample sensor data is reported to the device. Whether the sensor hardware works or not, the sampling accuracy is controlled by users. Therefore, the working method of the sensor is bidirectional, that is, controlling the control flow of the hardware and the data flow reported by the hardware. This also determines the sensor framework is different from the conventional input subsystem such as the touch screen.
This chapter mainly studies the sensor framework code and the Implementation Details of sensorhal. Everything starts from the sensor framework. First, let's review the implementation framework of LED Hal.
Led Hal is implemented by ourselves and mainly divided into four parts:
Led app: LED Application
Led service framework: API provider of LED applications
Ledservice local: local implementation of the ledservice, communication and conversion interfaces between the upper layer and the bottom layer
Led Hal stub: Hal-Layer Code, specific hardware driver operation interface
Obviously, the LED Hal code we wrote is a typical control flow, and the feedback result is the lighting and removal of the LED. Its architecture is not applicable to the sensor architecture. The details are as follows:
L led is a pure control flow, while sensor is a control flow and data flow
The data stream of the sensor is not real-time, but has a sampling rate, and the data is not continuous. It is blocked in reading data from hardware devices and is returned only when the data is obtained.
L sensor is a general framework provided to all sensors, not a specific hardware architecture.
The sensor contains multiple types. Both the upper layer and the bottom layer mask the specific type of the sensor so that it can use all the sensors.
L The sensor service is not created and started by the application, and should be started along with the system.
The sensor service can be used in any application, which determines that the sensor service should be started along with the system.
2. Sensor Framework Analysis
This section is the framework of the First Specific Device analyzed in this series. It starts from registering and starting Android sensorservice and obtains the sensormanager registration sensor listener from the application, analyze the entire process from the application layer to the Java framework layer to the local code, and finally call the Hal layer.
1.1 enable the sensor Service
According to the previous Android Startup Process chapter, after zygote is started, every JAVA process running is systemserver, which is used to start and manage all android services:
[CPP]
View plaincopyprint?
- Public staticvoid main (string [] ARGs ){
- ...
- System. loadlibrary ("android_servers ");
- Init1 (ARGs );
- }
public static void main(String[] args) { … System.loadLibrary("android_servers"); init1(args); }
According to the main method of systemserver, it loads the libandroid_servers.so library and calls the init1 () method.
The following command is used to find the compiling directory of the Library:
[Plain]
View plaincopyprint?
- Find./frameworks/base-name Android. mk-exec grep-l libandroid_servers {}\;
find ./frameworks/base –name Android.mk –exec grep –l libandroid_servers{}\;
The printed information shows that the source code directory is: Frameworks/base/services/JNI, in fact, the code at the android framework layer is characterized by the corresponding Java framework code stored in the Java directory, and the corresponding local code under the corresponding JNI directory.
The most important code in this directory is: com_android_server_systemserver.cpp:
[CPP]
View plaincopyprint?
- Namespace Android {
- Extern "C" int system_init ();
- Static void android_server_systemserver_init1 (jnienv * ENV, jobject clazz)
- {
- System_init ();
- }
- /*
- * Jniregistration.
- */
- Static jninativemethod gmethods [] = {
- /* Name, signature, funcptr */
- {"Init1", "([ljava/lang/string;) V", (void *) android_server_systemserver_init1 },
- };
- Int register_android_server_systemserver (jnienv * env)
- {
- Returnjniregisternativemethods (ENV, "com/Android/Server/systemserver ",
- Gmethods, nelem (gmethods ));
- }
- }; // Namespace android
namespace android {extern "C" int system_init();static void android_server_SystemServer_init1(JNIEnv*env, jobject clazz){ system_init();}/* * JNIregistration. */static JNINativeMethod gMethods[] = { /* name,signature, funcPtr */ {"init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1},};int register_android_server_SystemServer(JNIEnv* env){ returnjniRegisterNativeMethods(env, "com/android/server/SystemServer", gMethods, NELEM(gMethods));}}; // namespace android
There are not many codes and it is easy to read. Calling the jniregisternativemethods method to register the Java method of systemserver also has a local method ing relationship. jniregisternativemethods is the Helper Method for registering a local method.
Systemserver. after Java loads the libandroid_servers.so library, it calls init1 (). The ing relationship in the code above shows that it calls the local android_server_systemserver_init1 method, which calls system_init () directly (), in fact, it is implemented in frameworks/base/cmds/system_server/library/system_init.cpp:
[CPP]
View plaincopyprint?
- Extern "C" status_t system_init ()
- {
- Logi ("entered system_init ()");
- Sp <processstate> proc (processstate: Self ());
- Sp <iservicemanager> Sm = defaultservicemanager ();
- Logi ("servicemanager: % P \ n", Sm. Get ());
- Sp <grimreaper> grim = new grimreaper ();
- SM-> asbinder ()-> linktodeath (grim, Grim. Get (), 0 );
- Charpropbuf [property_value_max];
- Property_get ("system_init.startsurfaceflinger", propbuf, "1 ");
- If (strcmp (propbuf, "1") = 0 ){
- // Startthe surfaceflinger
- Surfaceflinger: instantiate ();
- }
- Property_get ("system_init.startsensorservice", propbuf, "1 ");
- If (strcmp (propbuf, "1") = 0 ){
- // Startthe sensor Service
- Sensorservice: instantiate ();
- }
- Logi ("systemserver: Starting Android runtime. \ n ");
- Androidruntime * runtime = androidruntime: getruntime ();
- Logi ("system server: Starting Android services. \ n ");
- Jnienv * Env = runtime-> getjnienv ();
- If (ENV = NULL ){
- Returnunknown_error;
- }
- Jclass clazz = env-> findclass ("com/Android/Server/systemserver ");
- If (clazz = NULL ){
- Returnunknown_error;
- }
- Jmethodidmethodid = env-> getstaticmethodid (clazz,
"Init2", "() V ");
- If (methodid = NULL ){
- Returnunknown_error;
- }
- Env-> callstaticvoidmethod (clazz, methodid );
- Logi ("system server: Entering thread pool. \ n ");
- Processstate: Self ()-> startthreadpool ();
- Ipcthreadstate: Self ()-> jointhreadpool ();
- Logi ("system server: exiting thread pool. \ n ");
- }
extern "C" status_t system_init(){ LOGI("Entered system_init()"); sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); LOGI("ServiceManager: %p\n", sm.get()); sp<GrimReaper> grim = new GrimReaper(); sm->asBinder()->linkToDeath(grim, grim.get(), 0); charpropBuf[PROPERTY_VALUE_MAX]; property_get("system_init.startsurfaceflinger", propBuf,"1"); if(strcmp(propBuf, "1") == 0) { // Startthe SurfaceFlinger SurfaceFlinger::instantiate(); } property_get("system_init.startsensorservice", propBuf,"1"); if(strcmp(propBuf, "1") == 0) { // Startthe sensor service SensorService::instantiate(); } LOGI("Systemserver: starting Android runtime.\n"); AndroidRuntime* runtime = AndroidRuntime::getRuntime(); LOGI("System server: starting Android services.\n"); JNIEnv* env =runtime->getJNIEnv(); if (env ==NULL) { returnUNKNOWN_ERROR; } jclass clazz= env->FindClass("com/android/server/SystemServer"); if (clazz ==NULL) { returnUNKNOWN_ERROR; } jmethodIDmethodId = env->GetStaticMethodID(clazz, "init2","()V"); if (methodId== NULL) { returnUNKNOWN_ERROR; } env->CallStaticVoidMethod(clazz, methodId); LOGI("System server: entering thread pool.\n"); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); LOGI("System server: exiting thread pool.\n");}
If you understand the Binder Mechanism, you should know that sp <processstate> proc (processstate: Self ()) open the binder driver and create a processstate object and maintain the binder communication of the current process on the server side.
If the system_init.startsensorservice attribute is set to 1 in the system attribute, the sensor service is started through sensorservice: instantiate.
The biggest headache for beginners is to catch up with the heavy loads in the object-oriented code and rewrite the code. sensorservice: instantiate () calls the method of its parent class, we can find the inheritance relationship through the definition of the subclass, and then follow the inheritance relationship to find the implementation of the method. If there is a method implementation in both the subclass and the parent class, the parameter matching means that if the Parameters match each other, it is called rewrite and the subclass method is called. The sensorservice is defined as follows:
@ Frameworks/base/services/sensorservice/sensroservice. h
[CPP]
View plaincopyprint?
- Class sensorservice:
- Publicbinderservice <sensorservice>,
- Publicbnsensorserver,
- Protectedthread
- {
class SensorService : publicBinderService<SensorService>, publicBnSensorServer, protectedThread{
According to the sensorservice definition, there is no instantiate method declaration in the current class, indicating that it calls the method of the parent class and inherits the binderservice, bnsensorserver, thread class (is sensorservice a thread ??), Find the inheritance link and find the instantiate method declaration in binderservice.
@ Frameworks/base/include/binder/binderservice. h
[CPP]
View plaincopyprint?
- Template <typename service>
- Class binderservice
- {
- Public:
- Static status_t publish (){
- Sp <iservicemanager> SM (defaultservicemanager ());
- Returnsm-> addservice (string16 (Service: getservicename ()),
New Service ());
- }
- Static void publishandjointhreadpool (){
- Sp <processstate> proc (processstate: Self ());
- Sp <iservicemanager> SM (defaultservicemanager ());
- SM-> addservice (string16 (Service: getservicename ()),
New Service ());
- Processstate: Self ()-> startthreadpool ();
- Ipcthreadstate: Self ()-> jointhreadpool ();
- }
- Static void instantiate () {publish ();}
- Static status_t Shutdown (){
- Return no_error;
- }
- };
template<typename SERVICE>class BinderService{public: static status_t publish() { sp<IServiceManager> sm(defaultServiceManager()); returnsm->addService(String16(SERVICE::getServiceName()), new SERVICE()); } static void publishAndJoinThreadPool() { sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm(defaultServiceManager()); sm->addService(String16(SERVICE::getServiceName()), new SERVICE()); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); } static void instantiate() { publish(); } static status_t shutdown() { return NO_ERROR; }};
According to the code analysis above, the instantiate method creates the sensorservice and adds the newly created sensorservice to the android service list through addservice.
OK, then we will go to the sensorservice service.
@ Frameworks/base/services/sensorservice. cpp
[CPP]
View plaincopyprint?
- Sensorservice: sensorservice ()
- : Minitcheck (no_init)
- {
- }
- Void sensorservice: onfirstref ()
- {
- Logd ("nusensorservice starting ...");
- Sensordevice & Dev (sensordevice: getinstance ());
- ...
SensorService::SensorService() :mInitCheck(NO_INIT){}void SensorService::onFirstRef(){ LOGD("nuSensorService starting..."); SensorDevice& dev(SensorDevice::getInstance());…
The sensorservice construction method is relatively simple, and the minitcheck member variable is initialized to no_init.
Pay attention to the onfirstref method after the constructor method, which is a reference method in the counting system in the Android system. The method is automatically called when the refbase subclass object is strongly referenced for the first time. Therefore, this method is automatically called back when the sensorservice is used for the first time.
Shape:
[CPP]
View plaincopyprint?
- Sp <isensorserver> SM (msensorservice );
sp< ISensorServer> sm(mSensorService);
Note: If you are not familiar with the reference counting system, please refer to instructor Deng fanping's: deep understanding: three axes in Android core volume I.
The start of the sensorservice is paused. Wait for the upper-layer application to use the sensorservice and call the onfirstref method.