Sensor workflow in android

Source: Internet
Author: User

Work AndroidJNIthreadOS
JAVA program
We use the sensor interface to register the SensorListener as follows:
**************************************** **********************
ApiDemo:
MGraphView = new GraphView (this );
MSensorManager. registerListener (mGraphView ,....);
**************************************** **********************
The listener here is the control that changes when the sensor status changes.
Reload the on

SensorChanged and onAccuracyChanged Methods
Public void onSensorChanged (int sensor, float [] values)
Public void onAccuracyChanged (int sensor, int accuracy)
SensorManager
The Sensor main code and process are in frameworks/base/core/java/android/hardware/SensorManager. java.
1. registerListener actually calls registerLegacyListener:
Public boolean registerListener (SensorListener listener, int sensors, int rate ){
...
Result = registerLegacyListener (...);
...
}
2. registerLegacyListener is actually to construct a LegacyListener object and add it to HashMap.
Private boolean registerLegacyListener (int legacyType, int type,
SensorListener listener, int sensors, int rate)
{
...
LegacyListener = new LegacyListener (listener );
MLegacyListenersMap. put (listener, legacyListener); // private HashMap <SensorListener,
LegacyListener> mLegacyListenersMap
...
}
3. LegacyListener does two things: one is to call the two interfaces that we reload, and the other is
Data is flushed to our device display interface.
Private class LegacyListener implements SensorEventListener {
...
LegacyListener (SensorListener target ){
MTarget = target;
MSensors = 0;
}
Public void onSensorChanged (SensorEvent event ){
...
MapSensorDataToWindow ();
MTarget. onSensorChanged (...); // private SensorListener mTarget;
...
}
Public void onAccuracyChanged (Sensor sensor, int accuracy ){
...
}
}
The code is followed by some native methods:
Private static native void nativeClassInit (); // called in the SensorManager Constructor
Private static native int sensors_module_init (); // called in the SensorManager Constructor
Private static native int sensors_module_get_next_sensor (Sensor sensor, int
Next); // calls in the SensorManager Constructor
// Used within this module from outside SensorManager, don't make private
Static native int sensors_data_init (); // called in the SensorThread Construction
Static native int sensors_data_uninit (); // calls in the SensorThread destructor
Static native int sensors_data_open (FileDescriptor fd); // The run () loop call of SensorThread
Static native int sensors_data_close (); // The run () of SensorThread is called cyclically.
Static native int sensors_data_poll (float [] values, int [] status, long [] timestamp); // SensorThread
Run ()
Relationship between SensorManager and IsensorService
SensorManager calls IsensorService only by calling the service method to control whether thread is Lock.
Void startLocked (ISensorService service ){
...
ParcelFileDescriptor fd = service. getDataChanel ();
...
}
Or open
MSensorService. enableSensor (l, name, handle, delay );
This is how IsensorService instances are obtained.
MSensorService = ISensorService. Stub. asInterface (
ServiceManager. getService (Context. SENSOR_SERVICE ));
IsensorService is defined through aidl
Interface ISensorService
{
ParcelFileDescriptor getDataChanel ();
Boolean enableSensor (IBinder listener, String name, int sensor, int enable );
}
SensorService
Frameworks/base/services/java/com/android/server/SensorService. java
Class SensorService extends ISensorService. Stub {
...
}
The service was eventually transferred to the manager by the standard android process. We don't care about it. What we want to know is
EnableSensor implementation
First, you must have electricity
If (enable = SENSOR_DISABLE ){
MBatteryStats. noteStopSensor (uid, sensor );
} Else {
MBatteryStats. noteStartSensor (uid, sensor );
}
Check whether the sensor can be enabled.
If (enable! = SENSOR_DISABLE &&! _ Sensors_control_activate (sensor, true )){
Log. w (TAG, "cocould not enable sensor" + sensor );
Return false;
}
If the sensor is enabled, we need to listen to the status and report the status change to the outside.
If (l = null & enable! = SENSOR_DISABLE ){
L = new Listener (binder );
Binder. linkToDeath (l, 0 );
MListeners. add (l );
MListeners. Policy ();
}
If the sensor is disabled, we need to cancel the listener and tell the outside that the sensor is disabled.
If (enable! = SENSOR_DISABLE ){
L. addSensor (sensor, enable );
} Else {
L. removeSensor (sensor );
DeactivateIfUnused (sensor );
If (l. mSensors = 0 ){
MListeners. remove (l );
Binder. unlinkToDeath (l, 0 );
MListeners. Policy ();
}
}
There are also some actions to wake up and set latency
If (mListeners. size () = 0 ){
_ Sensors_control_wake ();
}
If (minDelay> = 0 ){
_ Sensors_control_set_delay (minDelay );
}
It can be seen from the above that for the underlying layer, as long as you know how to call the sensing interface on the upper layer, the most important thing is
The sensing process at the upper layer of the green native method is actually relatively simple, that is, the standard service management and notify process.
Private static native int _ sensors_control_init ();
Private static native ParcelFileDescriptor _ sensors_control_open ();
Private static native boolean _ sensors_control_activate (int sensor, boolean activate );
Private static native int _ sensors_control_set_delay (int MS );
Private static native int _ sensors_control_wake ();
Native METHOD
1. manager
Frameworks/base/core/jni/android_hardware_SensorManager.cpp
Let's take a look at its method registration.
Static JNINativeMethod gMethods [] = {
{"NativeClassInit", "() V", (void *) nativeClassInit },
{"Sensors_module_init", "() I", (void *) sensors_module_init },
{"Sensors_module_get_next_sensor", "(Landroid/hardware/Sensor; I) I ",
(Void *) sensors_module_get_next_sensor },
{"Sensors_data_init", "() I", (void *) sensors_data_init },
{"Sensors_data_uninit", "() I", (void *) sensors_data_uninit },
{"Sensors_data_open", "(Ljava/io/FileDescriptor;) I", (void *) sensors_data_open },
{"Sensors_data_close", "() I", (void *) sensors_data_close },
{"Sensors_data_poll", "([F [I [J) I", (void *) sensors_data_poll },
};
Paste an example as a representative
Static jint
Sensors_data_open (JNIEnv * env, jclass clazz, jobject fdo)
{
Jclass FileDescriptor = env-> FindClass ("java/io/FileDescriptor ");
JfieldID offset = env-> GetFieldID (FileDescriptor, "descriptor", "I ");
Int fd = env-> GetIntField (fdo, offset );
Return sSensorDevice-> data_open (sSensorDevice, fd); // doesn' t take ownership of fd
}
The sSensorDevice method is used at the end of the call.
/*
* The method below are not thread-safe and not intended to be
*/
Static sensors_data_device_t * sSensorDevice = 0;
2. service Section
Frameworks/base/services/jni/com_android_server_SensorService.cpp
Let's take a look at its method registration.
Static JNINativeMethod gMethods [] = {
{"_ Sensors_control_init", "() I", (void *) android_init },
{"_ Sensors_control_open", "() Landroid/OS/ParcelFileDescriptor;", (void *) android_open },
{"_ Sensors_control_activate", "(IZ) Z", (void *) android_activate },
{"_ Sensors_control_wake", "() I", (void *) android_data_wake },
{"_ Sensors_control_set_delay", "(I) I", (void *) android_set_delay },
};
Then the above methods are different and I have provided an example to illustrate the implementation.
Static jboolean
Android_activate (JNIEnv * env, jclass clazz, jint sensor, jboolean activate)
{
Int active = sSensorDevice-> activate (sSensorDevice, sensor, activate );
Return (active <0 )? False: true;
}
So the last call is actually the sSensorDevice method. Others are also like this: sSensorDevice is
(Not thread-safe)
/*
* The method below are not thread-safe and not intended to be
*/
Static sensors_control_device_t * sSensorDevice = 0;
3. Continue to catch up with the hardware layer. The last method is actually here.
Hardware/libhardware/include/hardware/sensor. h
Struct sensors_control_device_t {
Struct hw_device_t common;
/**
* Returns the fd which will be the parameter
* Sensors_data_device_t: open_data ().
* The caller takes ownership of this fd. This is intended to be
* Passed cross processes.
*
* @ Return a fd if successful, <0 on error
*/
Int (* open_data_source) (struct sensors_control_device_t * dev );
/** Activate/deactivate one sensor.
*
* @ Param handle is the handle of the sensor to change.
* @ Param enabled set to 1 to enable, or 0 to disable the sensor.
*
* @ Return 0 on success, negative errno code otherwise
*/
Int (* activate) (struct sensors_control_device_t * dev,
Int handle, int enabled );
/**
* Set the delay between sensor events in MS
*
* @ Return 0 if successful, <0 on error
*/
Int (* set_delay) (struct sensors_control_device_t * dev, int32_t MS );
/**
* Causes sensors_data_device_t.poll () to return-EWOULDBLOCK immediately.
*/
Int (* wake) (struct sensors_control_device_t * dev );
};
Struct sensors_data_device_t {
Struct hw_device_t common;
/**
* Prepare to read sensor data.
*
* This routine does NOT take ownership of the fd
* And must not close it. Typically this routine wowould
* Use a duplicate of the fd parameter.
*
* @ Param fd from sensors_control_open.
*
* @ Return 0 if successful, <0 on error
*/
Int (* data_open) (struct sensors_data_device_t * dev, int fd );
/**
* Caller has completed using the sensor data.
* The caller will not be blocked in sensors_data_poll
* When this routine is called.
*
* @ Return 0 if successful, <0 on error
*/
Int (* data_close) (struct sensors_data_device_t * dev );
/**
* Return sensor data for one of the enabled sensors.
*
* @ Return sensor handle for the returned data, 0x7FFFFFFF when
* Sensors_control_device_t.wake () is called and-errno on error
*
*/
Int (* poll) (struct sensors_data_device_t * dev,
Sensors_data_t * data );
};
Last group of functions
/** Convenience API for opening and closing a device */
Static inline int sensors_control_open (const struct hw_module_t * module,
Struct sensors_control_device_t ** device ){
Return module-> methods-> open (module,
SENSORS_HARDWARE_CONTROL, (struct hw_device_t **) device );
}
Static inline int sensors_control_close (struct sensors_control_device_t * device ){
Return device-> common. close (& device-> common );
}
Static inline int sensors_data_open (const struct hw_module_t * module,
Struct sensors_data_device_t ** device ){
Return module-> methods-> open (module,
SENSORS_HARDWARE_DATA, (struct hw_device_t **) device );
}
Static inline int sensors_data_close (struct sensors_data_device_t * device ){
Return device-> common. close (& device-> common );
}

 

This article is from "ajq1987"
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.