(1)Gsensor的注册和监听
App -->I2C过程:App通过SensorManager.getSystemServer调用到SystemSensorManager,SystemSensorManager通过jni调用到SensorManager.cpp,后通过binder调用到SensorService。SensorService通过SystemServer启动,后调用到hal kernel。
I2C -->App过程:通过JNI调用到SystemSensorManager中的SensorEventQueue.dispatchSensorEvent,然后通过App向SensorEventQueue注册的mListener,来回调数据到App的onSensorChanged()方法。
(网图)
//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, int maxReportLatencyUs) {
int delay = getDelay(samplingPeriodUs);
return registerListenerImpl(listener, sensor, delay, null, maxReportLatencyUs, 0);
}
public boolean registerListener(SensorEventListener listener, Sensor sensor,
int samplingPeriodUs, Handler handler) {
int delay = getDelay(samplingPeriodUs);
return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
}
public boolean registerListener(SensorEventListener listener, Sensor sensor,
int samplingPeriodUs, int maxReportLatencyUs, Handler handler) {
int delayUs = getDelay(samplingPeriodUs);
return registerListenerImpl(listener, sensor, delayUs, handler, maxReportLatencyUs, 0);
}
/** @hide */
protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags);
registerListenerImpl的具体实现如下:
//frameworks/base/core/java/android/hardware/SystemSensorManager.java
public class SystemSensorManager extends SensorManager {
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();
//这里创建SensorEventQueue,并调用addSensor进而调用addSensorEvent函数
queue = new SensorEventQueue(listener, looper, this, fullClassName);
if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
}
mSensorListeners.put(listener, queue);
return true;
} else {
return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
}
}
}
}
接下来我们看一下SensorEventQueue队列
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);
//App传过来的监听器进行赋值
mListener = listener;
}
@Override
public void addSensorEvent(Sensor sensor) {
SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,
mManager.mTargetSdkLevel));
synchronized (mSensorsEvents) {
mSensorsEvents.put(sensor.getHandle(), t);
}
}
@Override
public void removeSensorEvent(Sensor sensor) {
synchronized (mSensorsEvents) {
mSensorsEvents.delete(sensor.getHandle());
}
}
// Called from native code.
@SuppressWarnings("unused")
@Override
//在addSensorEvent put事件后,通过mSensorsEvents.get获取事件,然后通过mListener分发,这里的mListener就是App传过来的监听接口
protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
long timestamp) {
final Sensor sensor = mManager.mHandleToSensor.get(handle);
if (sensor == null) {
// sensor disconnected
return;
}
SensorEvent t = null;
synchronized (mSensorsEvents) {
t = mSensorsEvents.get(handle);
}
//...
//这里会回调注册过的监听器的onSensorChanged
mListener.onSensorChanged(t);
}
}
后续文章所提及的屏幕旋转方向等都和这里事件分发相关。
(2)应用注册屏幕旋转事件监听
应用注册使用,通过enable和disable来控制注册和取消注册
private class OrientationEventListenerImpl extends OrientationEventListener {
public OrientationEventListenerImpl(Context context) {
super(context);
}
@Override
public void onOrientationChanged(int orientation) {
if (orientation == ORIENTATION_UNKNOWN) {
return;
}
//...
}
}
mOrientationListener.enable();
mOrientationListener.disable();
如下为系统代码
//frameworks/base/core/java/android/view/OrientationEventListener.java
public abstract class OrientationEventListener {
public OrientationEventListener(Context context) {
this(context, SensorManager.SENSOR_DELAY_NORMAL);
}
public OrientationEventListener(Context context, int rate) {
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
mRate = rate;
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (mSensor != null) {
// Create listener only if sensors do exist
mSensorEventListener = new SensorEventListenerImpl();
}
}
public void enable() {
if (mSensor == null) {
Log.w(TAG, "Cannot detect sensors. Not enabled");
return;
}
if (mEnabled == false) {
if (localLOGV) Log.d(TAG, "OrientationEventListener enabled");
mSensorManager.registerListener(mSensorEventListener, mSensor, mRate);
mEnabled = true;
}
}
public void disable() {
if (mSensor == null) {
Log.w(TAG, "Cannot detect sensors. Invalid disable");
return;
}
if (mEnabled == true) {
if (localLOGV) Log.d(TAG, "OrientationEventListener disabled");
mSensorManager.unregisterListener(mSensorEventListener);
mEnabled = false;
}
}
class SensorEventListenerImpl implements SensorEventListener {
private static final int _DATA_X = 0;
private static final int _DATA_Y = 1;
private static final int _DATA_Z = 2;
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
int orientation = ORIENTATION_UNKNOWN;
float X = -values[_DATA_X];
float Y = -values[_DATA_Y];
float Z = -values[_DATA_Z];
float magnitude = X*X + Y*Y;
// Don't trust the angle if the magnitude is small compared to the y value
if (magnitude * 4 >= Z*Z) {
float OneEightyOverPi = 57.29577957855f;
float angle = (float)Math.atan2(-Y, X) * OneEightyOverPi;
orientation = 90 - (int)Math.round(angle);
// normalize to 0 - 359 range
while (orientation >= 360) {
orientation -= 360;
}
while (orientation < 0) {
orientation += 360;
}
}
if (mOldListener != null) {
mOldListener.onSensorChanged(Sensor.TYPE_ACCELEROMETER, event.values);
}
if (orientation != mOrientation) {
mOrientation = orientation;
//回调函数
onOrientationChanged(orientation);
}
}
//回调函数
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
}