1.1 Sensor Architecture

1.1.1. Data transmission mode

app - > I2C process: app calls to System Sensor Manager System Sensor Manager System Sensor Manager through Sensor Manager, getSystem Server calls to Sensor Manager. CPP through jni, and Sensor Service through binder creation connection.

SensorService is started through System Server, and Sensor calls to hal kernel

I2c delivers data to app: SensorService is a binder thread, device.poll in threadloop method reads and sends data, and sends data to app through BitTube (cross-process socket) sendEvents. android_hardware_SensorManager.cpp In this jni,

Through JNI calls, the SensorEventQueue.dispatchSensorEvent in the java layer System Sensor Manager is invoked, and the mListener registered with SensorEventQueue by app calls back the data to the onSensorChanged() method of app.

 

 

1.2  mSensorManager.registerListener

@frameworks/base/core/java/android/hardware/SensorManager.java
public boolean registerListener(SensorEventListener listener, Sensor sensor,
        int samplingPeriodUs) {
    return registerListener(listener, sensor, samplingPeriodUs, null);
}

public boolean registerListener(SensorEventListener listener, Sensor sensor,
        int samplingPeriodUs, Handler handler) {
    int delay = getDelay(samplingPeriodUs);
    return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
}

/** @hide */
protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
        int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags);
@SystemSensorManager.java
public class SystemSensorManager extends SensorManager {
    @Override
    protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
        ...
        synchronized (mSensorListeners) {
            SensorEventQueue queue = mSensorListeners.get(listener);
            if (queue == null) {
                Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
                final String fullClassName = listener.getClass().getEnclosingClass() != null ?
                    listener.getClass().getEnclosingClass().getName() :
                    listener.getClass().getName();
                queue = new SensorEventQueue(listener, looper, this, fullClassName);   //SensorEventQueue
                if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {    //addSensor
                    queue.dispose();
                    return false;
                }
                mSensorListeners.put(listener, queue);
                return true;
            } else {
                return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
            }
        }
    }

 

//SensorEventQueue inherits BaseEventQueue
static final class SensorEventQueue extends BaseEventQueue {
private final SensorEventListener mListener;
private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();

public SensorEventQueue(SensorEventListener listener, Looper looper,
        SystemSensorManager manager, String packageName) {
    super(looper, manager, OPERATING_MODE_NORMAL, packageName);
    mListener = listener;     //app registration Service registers this Listener
}

//Write SensorEvent to addSensorEvent
@Override
public void addSensorEvent(Sensor sensor) {
    SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,
            mManager.mTargetSdkLevel));
    synchronized (mSensorsEvents) {
        mSensorsEvents.put(sensor.getHandle(), t);    //mSensorsEvents.put
    }
}

//After the addSensorEvent put event, get the event through mSensorsEvents.get and distribute it through mListener, where mListener is passed through app
// Called from native code.
@SuppressWarnings("unused")
@Override
protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
        long timestamp) {
    synchronized (mSensorsEvents) {
        t = mSensorsEvents.get(handle);   //mSensorsEvents.get
    }

    // call onAccuracyChanged() only if the value changes
    final int accuracy = mSensorAccuracies.get(handle);
    if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
        mSensorAccuracies.put(handle, t.accuracy);
        mListener.onAccuracyChanged(t.sensor, t.accuracy);   //onAccuracyChanged
    }
    mListener.onSensorChanged(t);   //Callback onSensorChanged, where mListener and application are identical
}

 

Client sends data

After the handleEvent method obtains the data, it calls back the dispatchSensorEvent method of the internal class SensorEventQueue of the Java layer SystemSensorManager.

env->CallVoidMethod(receiverObj.get(),gBaseEventQueueClassInfo.dispatchSensorEvent,

buffer[i].sensor, mScratch, status, buffer[i].timestamp);

Finally, call the registered onSensorChanged to spit out the data