一、Sensor Framework 整体框架
前面分析了Android Sensor的 kernel 和 hal 部分,接下来我们再看sensor 的framework 部分。Android framerwork 封装了android 系统自己的核心框架,其中对Sensor 处理有着它自己的一套机制, 这一部分主要有 Sensor Service 构成,主要实现了 Sensor 数据流和控制流。Android SensorFramework 的总体关系类图如下:
Android中Service是不能够直接访问的,需要使用client请求来完成,client主要负责发送请求数据,接收server端分发的数据,而server端主要负责从使能底层sensor,从底层获取数据,响应client的请求.
Android SensorFramework 的总体关系类调用序列图如下:
在上面序列图中,我们可以把整个图分成两路,一个是从应用层到HAL层的通道主要负责enableSensor(图中从左到右),一个是从HAL层到应用层的通道(从右到左)主要负责dispatch Sensor数据。
二、Sensor架构的具体实现
================================================================================================================
第一部分:client端到Server端
================================================================================================================
先来分析enableSensor部分,这一路接口调用的缩略如下:
registerListener->>
registerListenerImpl->>
queue = new SensorEventQueue->>
queue.addSensor->>enableSensor->>
nativeEnableSensor->>enableSensor->>enableDisable->>enable->>sensor->activate()->>
|HardwareSensor::activate->>mSensorDevice.activate(已经抵达HAL层)
|
|
->>nativeInitSensorEventQueue->>new Receiver->>OnFirstRef->>mMessageQueue->>getLooper()->>
addFd(set up Receiver LooperCallback)
具体实现看下面分析:以下为SystemSensorManager的registerListener函数:
文件:./framework/base/core/java/android/hardware/SensorManager.java
public boolean <span style="color:#ff0000;">registerListener</span>(SensorListener listener, int sensors, int rate) {
return <span style="color:#ff0000;">getLegacySensorManager().registerListener</span>(listener, sensors, rate);
}
registerListener函数调用getLegacySensorManager()返回对象如下:
private LegacySensorManager <span style="color:#ff0000;">getLegacySensorManager</span>() {
synchronized (mSensorListByType) {
if (mLegacySensorManager == null) {
Log.i(TAG, "This application is using deprecated SensorManager API which will "
+ "be removed someday. Please consider switching to the new API.");
mLegacySensorManager = new <span style="color:#ff0000;">LegacySensorManager</span>(this);
}
return <span style="color:#ff0000;">mLegacySensorManager</span>;
}
}
文件:frameworks/base/core/java/android/hardware/LegacySensorManager.java
getLegacySensorManager创建LegacySensorManager对象构造器如下:
public <span style="color:#ff0000;">LegacySensorManager</span>(SensorManager sensorManager) {
mSensorManager = sensorManager;
synchronized (SensorManager.class) {
if (!sInitialized) {
sWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
if (sWindowManager != null) {
// if it's null we're running in the system process
// which won't get the rotated values
try {
sRotation = sWindowManager.watchRotation(
new IRotationWatcher.Stub() {
public void onRotationChanged(int rotation) {
LegacySensorManager.onRotationChanged(rotation);
}
}
);
} catch (RemoteException e) {
}
}
}
}
}
LegacySensorManager的registerListener(listener, sensors, rate)定义如下:
public boolean <span style="color:#ff0000;">registerListener</span>(SensorListener listener, int sensors, int rate) {
if (listener == null) {
return false;
}
boolean result = false;
result = <span style="color:#ff0000;">registerLegacyListener</span>(SensorManager.SENSOR_ACCELEROMETER,
Sensor.TYPE_ACCELEROMETER, listener, sensors, rate) || result;
....
return result;
}
在registerListener(listener, sensors, rate)再调用重载方法
private boolean <span style="color:#ff0000;">registerLegacyListener</span>(int legacyType, int type,
SensorListener listener, int sensors, int rate) {
boolean result = false;
// Are we activating this legacy sensor?
if ((sensors & legacyType) != 0) {
// if so, find a suitable Sensor
Sensor sensor = mSensorManager.getDefaultSensor(type);
if (sensor != null) {
// We do all of this work holding the legacy listener lock to ensure
// that the invariants around listeners are maintained. This is safe
// because neither registerLegacyListener nor unregisterLegacyListener
// are called reentrantly while sensors are being registered or unregistered.
synchronized (mLegacyListenersMap) {
// If we don't already have one, create a LegacyListener
// to wrap this listener and process the events as
// they are expected by legacy apps.
LegacyListener legacyListener = mLegacyListenersMap.get(listener);
if (legacyListener == null) {
// we didn't find a LegacyListener for this client,
// create one, and put it in our list.
legacyListener = new LegacyListener(listener);
mLegacyListenersMap.put(listener, legacyListener);
}
// register this legacy sensor with this legacy listener
if (legacyListener.registerSensor(legacyType)) {
// and finally, register the legacy listener with the new apis
result = <span style="color:#ff0000;">mSensorManager.registerListener</span>(legacyListener, sensor, rate);
} else {
result = true; // sensor already enabled
}
}
}
}
return result;
}
上述注册方法又调用,mSensorManager.registerListener方法:
public boolean registerListener(SensorListener listener, int sensors, int rate) {
if (listener == null) {
return false;
}
boolean result = false;
result = registerLegacyListener(SensorManager.SENSOR_ACCELEROMETER,
Sensor.TYPE_ACCELEROMETER, listener, sensors, rate) || result;
result = registerLegacyListener(SensorManager.SENSOR_MAGNETIC_FIELD,
Sensor.TYPE_MAGNETIC_FIELD, listener, sensors, rate) || result;
result = registerLegacyListener(SensorManager.SENSOR_ORIENTATION_RAW,
Sensor.TYPE_ORIENTATION, listener, sensors, rate) || result;
result = registerLegacyListener(SensorManager.SENSOR_ORIENTATION,
Sensor.TYPE_ORIENTATION, listener, sensors, rate) || result;
result =<span style="color:#ff0000;"> registerLegacyListener</span>(SensorManager.SENSOR_TEMPERATURE,
Sensor.TYPE_TEMPERATURE, listener, sensors, rate) || result;
return result;
}
上述的方法中又调用registerLegacyListener方法入如下:
private boolean <span style="color:#ff0000;">registerLegacyListener</span>(int legacyType, int type,
SensorListener listener, int sensors, int rate) {
boolean result = false;
// Are we activating this legacy sensor?
if ((sensors & legacyType) != 0) {
// if so, find a suitable Sensor
Sensor sensor = mSensorManager.getDefaultSensor(type);
if (sensor != null) {
// We do all of this work holding the legacy listener lock to ensure
// that the invariants around listeners are maintained. This is safe
// because neither registerLegacyListener nor unregisterLegacyListener
// are called reentrantly while sensors are being registered or unregistered.
synchronized (mLegacyListenersMap) {
// If we don't already have one, create a LegacyListener
// to wrap this listener and process the events as
// they are expected by legacy apps.
LegacyListener legacyListener = mLegacyListenersMap.get(listener);
if (legacyListener == null) {
// we didn't find a LegacyListener for this client,
// create one, and put it in our list.
legacyListener = new LegacyListener(listener);
mLegacyListenersMap.put(listener, legacyListener);
}
// register this legacy sensor with this legacy listener
if (legacyListener.registerSensor(legacyType)) {
// and finally, register the legacy listener with the new apis
result = <span style="color:#ff0000;">mSensorManager.registerListener</span>(legacyListener, sensor, rate);
} else {
result = true; // sensor already enabled
}
}
}
}
return result;
}
上面的registerLegacyListener又再次调用registerListener如下:
public boolean <span style="color:#ff0000;">registerListener</span>(SensorEventListener listener, Sensor sensor,
int samplingPeriodUs) {
return <span style="color:#ff0000;">registerListener</span>(listener, sensor, samplingPeriodUs, null);
}
注意listener 类型, 先前调用listener 为SensorListener类型,而此时的legacyListener 为SensorEventListener类型SensorEventListener 为一个接口,作用只是提供两个方法而已,最终都会mTarget.onSensorChanged(legacyType,v)这个mTarget就是我们传进来的,也就是我们实现了SensorEventListener接口的类,所以这里就回到了应用程序的onSensorChanged把数据返回给应用,SensorEventListener实现对象类定义如下:
//定义 LegacyListener 类
private static final class LegacyListener implements SensorEventListener {
private SensorListener mTarget;
public void <span style="color:#ff0000;">onAccuracyChanged</span>(Sensor sensor, int accuracy) {
try {
<span style="color:#ff0000;">mTarget.onAccuracyChanged</span>(getLegacySensorType(sensor.getType()), accuracy);
} catch (AbstractMethodError e) {
// old app that doesn't implement this method
// just ignore it.
}
}
public void <span style="color:#cc0000;">onSensorChanged</span>(SensorEvent event) {
final float v[] = mValues;
v[0] = event.values[0];
v[1] = event.values[1];
v[2] = event.values[2];
int type = event.sensor.getType();
int legacyType = getLegacySensorType(type);
mapSensorDataToWindow(legacyType, v, LegacySensorManager.getRotation());
if (type == Sensor.TYPE_ORIENTATION) {
if ((mSensors & SensorManager.SENSOR_ORIENTATION_RAW)!=0) {
mTarget.onSensorChanged(SensorManager.SENSOR_ORIENTATION_RAW, v);
}
if ((mSensors & SensorManager.SENSOR_ORIENTATION)!=0) {
v[0] = mYawfilter.filter(event.timestamp, v[0]);
mTarget.onSensorChanged(SensorManager.SENSOR_ORIENTATION, v);
}
} else {
mTarget.<span style="color:#ff0000;">onSensorChanged</span>(legacyType, v); //在这里回调,UI线程既可以获得Sensor数据
}
}
......
}
接下来继续调用的registerListener方法如下:文件::./framework/base/core/java/android/hardware/SensorManager.java
public boolean <span style="color:#ff0000;">registerListener</span>(SensorEventListener listener, Sensor sensor,
int samplingPeriodUs, Handler handler) {
int delay = getDelay(samplingPeriodUs);
return <span style="color:#ff0000;">registerListenerImpl</span>(listener, sensor, delay, handler, 0, 0);
}
这一步很关键在Impl为实现的意思,到这里就意味着注册进入真正的实现阶段,如下:
文件:frameworks/base/core/java/android/hardware/SystemSensorManager.java
protected boolean <span style="color:#ff0000;">registerListenerImpl</span>(SensorEventListener listener, Sensor sensor,
int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
.....
// Invariants to preserve:
// - one Looper per SensorEventListener
// - one Looper per SensorEventQueue
// We map SensorEventListener to a SensorEventQueue, which holds the looper
synchronized (mSensorListeners) {
SensorEventQueue queue = mSensorListeners.get(listener);
if (queue == null) {
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
queue = <span style="color:#ff0000;">new SensorEventQueue</span>(listener, looper, this, fullClassName);
if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
}
mSensorListeners.put(listener, queue);
return true;
} else {
return <span style="color:#ff0000;">queue.addSensor</span>(sensor, delayUs, maxBatchReportLatencyUs);
}
}
}
registerListenerImpl 这个方法非常重要,基本上就是注册过程的核心逻辑,调用时传入listener ,listener对象作为 Sensor对象作为构造器参数被传入进去,通过mSensorListeners.get(listener)获得SensorEventQueue 对象,如果获取失败 ,则新建SensorEventQueue对象 ; handler.getLooper() 也就是说,在客户端register 阶段即创建线程时刻监听底层sensor 数据变化 。上面的registerListenerImpl函数中创建的SensorEventQueue对象如下:
static final class <span style="color:#ff0000;">SensorEventQueue </span>extends <span style="color:#ff0000;">BaseEventQueue </span>{
private final SensorEventListener mListener;
private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();
// Called from native code.
@SuppressWarnings("unused")
@Override
protected void <span style="color:#ff0000;">dispatchSensorEvent</span>(int handle, float[] values, int inAccuracy,
long timestamp) {
final Sensor sensor = mManager.mHandleToSensor.get(handle);
SensorEvent t = null;
synchronized (mSensorsEvents) {
t = mSensorsEvents.get(handle);
}
// 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);
<span style="color:#ff0000;">mListener.onAccuracyChanged</span>(t.sensor, t.accuracy);
}
<span style="color:#ff0000;">mListener.onSensorChanged</span>(t);
}
......
}
SensorEventQueue中定义了dispatchSensorEvent方法,该方法用于Senosr server端向client端分发数据,此外SensorEventQueue继承了类BaseEventQueue,BaseEventQueue的定义如下:
private static abstract class <span style="color:#ff0000;">BaseEventQueue </span>{
private static native long nativeInitBaseEventQueue(long nativeManager,
WeakReference<BaseEventQueue> eventQWeak, MessageQueue msgQ, float[] scratch,
String packageName, int mode, String opPackageName);
private static native int nativeEnableSensor(long eventQ, int handle, int rateUs,
int maxBatchReportLatencyUs);
private static native int nativeDisableSensor(long eventQ, int handle);
private static native void nativeDestroySensorEventQueue(long eventQ);
private static native int nativeFlushSensor(long eventQ);
BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {
if (packageName == null) packageName = "";
<span style="color:#ff0000;"> nSensorEventQueue = nativeInitBaseEventQueue</span>(manager.mNativeInstance,
new WeakReference<>(this), looper.getQueue(), mScratch,
packageName, mode, manager.mContext.getOpPackageName());
mCloseGuard.open("dispose");
mManager = manager;
}
.....
protected abstract void <span style="color:#ff0000;">dispatchSensorEvent</span>(int handle, float[] values, int accuracy,
long timestamp);
protected abstract void <span style="color:#ff0000;">addSensorEvent</span>(Sensor sensor);
}
从类BaseEventQueue中可以看出,该类封装了很多操作sensor的方法,如果我们调用了addSensor方法,在其中有调用enableSensor,这个方法十分关键,正是它的执行,是的底层sensor 被activate,sensor 就会正常工作继续观察SensorEventQueue对象的创建,在创建中会先创建父类对象:
BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {
if (packageName == null) packageName = "";
nSensorEventQueue = <span style="color:#ff0000;">nativeInitBaseEventQueue</span>(manager.mNativeInstance,
new WeakReference<>(this), looper.getQueue(), mScratch,
packageName, mode, manager.mContext.getOpPackageName());
mCloseGuard.open("dispose");
mManager = manager;
}
父类构造其中调用了本地方法nativeInitBaseEventQueue如下:
static jlong <span style="color:#ff0000;">nativeInitSensorEventQueue</span>(JNIEnv *env, jclass clazz, jlong sensorManager,
jobject eventQWeak, jobject msgQ, jfloatArray scratch, jstring packageName, jint mode) {
SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
ScopedUtfChars packageUtf(env, packageName);
String8 clientName(packageUtf.c_str());
sp<SensorEventQueue> <span style="color:#ff0000;">queue(mgr->createEventQueue</span>(clientName, mode));
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
<span style="color:#ff0000;"> sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak, scratch);</span>
<span style="color:#ff0000;">receiver->incStrong((void*)nativeInitSensorEventQueue);</span>
return jlong(receiver.get());
}
上述的nativeInitSensorEventQueue调用中会创建Receiver对象,Receiver对象类定义如下:
class <span style="color:#ff0000;">Receiver </span>: public <span style="color:#ff0000;">LooperCallback </span>{
sp<SensorEventQueue> mSensorQueue;
sp<MessageQueue> mMessageQueue;
jobject mReceiverWeakGlobal;
jfloatArray mScratch;
public:
Receiver(const sp<SensorEventQueue>& sensorQueue,
const sp<MessageQueue>& messageQueue,
jobject receiverWeak, jfloatArray scratch) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
mSensorQueue = sensorQueue;
mMessageQueue = messageQueue;
mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak);
mScratch = (jfloatArray)env->NewGlobalRef(scratch);
}
~Receiver() {
JNIEnv* env = AndroidRuntime::getJNIEnv();
env->DeleteGlobalRef(mReceiverWeakGlobal);
env->DeleteGlobalRef(mScratch);
}
......
};
从Receiver对象类中可以看到,构造对象时候,sensorQueue作为参数传入。Receiver创建后会自动执行onFirstRef如下:
virtual void <span style="color:#ff0000;">onFirstRef</span>() {
<span style="color:#ff0000;">LooperCallback</span>::onFirstRef();
<span style="color:#ff0000;">mMessageQueue->getLooper()->addFd(mSensorQueue->getFd</span>(), 0,
ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
}
在onFirstRef中,再执行mMessageQueue->getLooper()->addFd用来启动LoopCallback这句最关键了,
把channel的fd, 加到了looper的fd集合里, 并且传递了this进入,本身class Receiver : public LooperCallback
就是继承LooperCallback, 所以server端的fd动作(SendEvent), 都会被looper回调到Receiver的接口里, 实际
上是:Receiver::handleEvent, 我们知道q->read-->dispatchSensorEvent(见下文)就是从socket的fd读东西
了.再看registerListenerImpl中创建SensorEventQueue对象后,紧接着调用addSensor方法,addSensor的实
现如下:
public boolean <span style="color:#ff0000;">addSensor</span>(
Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
// Check if already present.
int handle = sensor.getHandle();
// Get ready to receive events before calling enable.
mActiveSensors.put(handle, true);
addSensorEvent(sensor);
if (<span style="color:#ff0000;">enableSensor</span>(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
// Try continuous mode if batching fails.
if (maxBatchReportLatencyUs == 0 ||
maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
removeSensor(sensor, false);
return false;
}
}
return true;
}
在addSensor方法中,又调用enableSensor(sensor, delayUs, maxBatchReportLatencyUs)函数,enableSensor的实现如下:
private int <span style="color:#ff0000;">enableSensor</span>(
Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
return <span style="color:#ff0000;">nativeEnableSensor</span>(nSensorEventQueue, sensor.getHandle(), rateUs,
maxBatchReportLatencyUs);
}
在enableSensor方法中又调用本地方法nativeEnableSensor,改方法实现如下:文件:frameworks/base/core/jni/android_hardware_SensorManager.cpp
static jint <span style="color:#ff0000;">nativeEnableSensor</span>(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
jint maxBatchReportLatency) {
sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
<span style="color:#ff0000;"> return receiver->getSensorEventQueue()->enableSensor</span>(handle, rate_us, maxBatchReportLatency, 0);
}
在上述接口中又会调用receiver->getSensorEventQueue()->enableSensor,这里先通过调用receiver对象的getSensorEventQueue()方法获得SensorEventQueue对象,再调用其enableSensor函数:
status_t <span style="color:#ff0000;">SensorEventQueue::enableSensor</span>(int32_t handle, int32_t samplingPeriodUs,
int maxBatchReportLatencyUs, int reservedFlags) const {
return<span style="color:#ff0000;"> mSensorEventConnection->enableDisable</span>(handle, true, us2ns(samplingPeriodUs),
us2ns(maxBatchReportLatencyUs), reservedFlags);
}
在上述的enableSensor中再次调用mSensorEventConnection->enableDisable方法,文件:frameworks/native/services/sensorservice/SensorService.cpp
status_t <span style="color:#ff0000;">SensorService::SensorEventConnection::enableDisable</span>(
int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
int reservedFlags)
{
status_t err;
if (enabled) {
err =<span style="color:#ff0000;"> mService->enable</span>(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
reservedFlags, mOpPackageName);
} else {
err = <span style="color:#ff0000;">mService->disable</span>(this, handle);
}
return err;
}
在mSensorEventConnection->enableDisable中又调用mService->enable
status_t <span style="color:#ff0000;">SensorService::enable</span>(const sp<SensorEventConnection>& connection,
int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
const String16& opPackageName)
{
......
status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
maxBatchReportLatencyNs);
err = <span style="color:#ff0000;">sensor->activate</span>(connection.get(), true);
......
}
在mService->enable又调用sensor->activate
status_t <span style="color:#ff0000;">SensorDevice::activate</span>(void* ident, int handle, int enabled)
{
......
err = <span style="color:#ff0000;">mSensorDevice->activate</span>(
reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
// On older devices which do not support batch, call setDelay().
<span style="color:#ff0000;">mSensorDevice->setDelay(</span>
reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
handle, info.bestBatchParams.batchDelay);
......
return err;
}
status_t <span style="color:#ff0000;">SensorDevice::activate</span>(void* ident, int handle, int enabled)
{
......
err =<span style="color:#ff0000;"> mSensorDevice->activate</span>(
reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
// On older devices which do not support batch, call setDelay().
<span style="color:#ff0000;">mSensorDevice->setDelay(</span>
reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
handle, info.bestBatchParams.batchDelay);
......
return err;
}
================================================================================================================
第二部分:server端到client端
================================================================================================================
前面讲完了客户端如何使能底层的sensor的第一条通道,接下来继续分析,Server端如何向client端反馈数据的第二条通道。dispatch Sensor数据部分,这一路接口调用的缩略如下:device.poll->>threadLoop()->>activeConnections[i]->sendEvents->>SensorEventQueue::write->>BitTube::sendObjects
-->Receiver::handleEvent-->>q->read-->dispatchSensorEvent->>onSensorChanged
具体实现看下面分析:以下为SensorService的threadLoop函数,在线程函数中调用SensorDevice::getInstance()获得设备对象,并且调用device.poll函数如下:
文件:frameworks/native/services/sensorservice/SensorService.cpp
bool<span style="color:#ff0000;"> SensorService::threadLoop</span>()
{
ALOGD("nuSensorService thread starting...");
// each virtual sensor could generate an event per "real" event, that's why we need
// to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.
// in practice, this is too aggressive, but guaranteed to be enough.
....
<span style="color:#ff0000;">SensorDevice& device(SensorDevice::getInstance());</span>
....
do {
ssize_t count = <span style="color:#ff0000;">device.poll</span>(mSensorEventBuffer, numEventMax);
if (count < 0) {
ALOGE("sensor poll failed (%s)", strerror(-count));
break;
}
......
// Send our events to clients. Check the state of wake lock for each client and release the
// lock if none of the clients need it.
bool needsWakeLock = false;
size_t numConnections = activeConnections.size();
for (size_t i=0 ; i < numConnections; ++i) {
if (activeConnections[i] != 0) {
<span style="color:#ff0000;"> activeConnections[i]->sendEvents</span>(mSensorEventBuffer, count, mSensorEventScratch,
mMapFlushEventsToConnections);
needsWakeLock |= activeConnections[i]->needsWakeLock();
.....
}
//这里有一种轮询机制,通判断锁的状态来确定是否有事件到来
if (mWakeLockAcquired && !needsWakeLock) {
setWakeLockAcquiredLocked(false);
}
} while (!Thread::exitPending());
.....
return false;
}
注意这里之所以能够调用线程函数是因为,SensorService 继承了线程类Thread,所以这个是线程函数,调用run 后线程即可启动,调用poll 函数不断轮询底层(HAL)层sensor状态,如果抓取到数据,则通过activeConnections
将数据发送给SensorManager 也就是客户端,其中SensorDevice的poll函数实现如下:
文件:frameworks/native/services/sensorservice/SensorDevice.cpp
ssize_t <span style="color:#ff0000;">SensorDevice::poll</span>(sensors_event_t* buffer, size_t count) {
if (!mSensorDevice) return NO_INIT;
ssize_t c;
do {
c = <span style="color:#ff0000;">mSensorDevice->poll</span>(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
buffer, count);
} while (c == -EINTR);
return c;
}
至于其中mSensorDevice的获得要看HAL部分实现,这里不再赘述,接下来请看server端的事件分发文件:frameworks/native/services/sensorservice/SensorService.cpp
threadLoop 线程中如果读取到数据,就通过activeConnections[i]->sendEvents将事件分发出去,如下
for (size_t i=0 ; i < numConnections; ++i) {
if (activeConnections[i] != 0) {
<span style="color:#ff0000;">activeConnections[i]->sendEvents</span>(mSensorEventBuffer, count, mSensorEventScratch,
mMapFlushEventsToConnections);
.....
}
}
分发事件函数sendEvents的实现如下
status_t <span style="color:#ff0000;">SensorService::SensorEventConnection::sendEvents</span>(
sensors_event_t const* buffer, size_t numEvents,
sensors_event_t* scratch,
SensorEventConnection const * const * mapFlushEventsToConnections) {
....
// NOTE: ASensorEvent and sensors_event_t are the same type.
ssize_t size = <span style="color:#ff0000;">SensorEventQueue::write</span>(mChannel,
reinterpret_cast<ASensorEvent const*>(scratch), count);
....
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
文件:frameworks/native/libs/gui/SensorEventQueue.cppsendEvents中调用的write函数如下:
ssize_t <span style="color:#ff0000;">SensorEventQueue::write</span>(const sp<BitTube>& tube,
ASensorEvent const* events, size_t numEvents) {
return<span style="color:#ff0000;"> BitTube::sendObjects</span>(tube, events, numEvents);
}
同理对应的read函数如下:
ssize_t<span style="color:#ff0000;"> SensorEventQueue::read</span>(ASensorEvent* events, size_t numEvents) {
if (mAvailable == 0) {
ssize_t err = <span style="color:#ff0000;">BitTube::recvObjects(</span>mSensorChannel,
mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
if (err < 0) {
return err;
}
mAvailable = static_cast<size_t>(err);
mConsumed = 0;
}
size_t count = min(numEvents, mAvailable);
memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));
mAvailable -= count;
mConsumed += count;
return static_cast<ssize_t>(count);
}
文件:frameworks/native/include/gui/BitTube.hframeworks/native/libs/gui/BitTube.cpp
BitTube 类的定义,其中声明了recvObjects、sendObjects接口
class BitTube : public RefBase
{
public:
// creates a BitTube with a default (4KB) send buffer
BitTube();
.....
// get receive file-descriptor
int getFd() const;
// get the send file-descriptor.
int getSendFd() const;
// send objects (sized blobs). All objects are guaranteed to be written or the call fails.
template <typename T>
static ssize_t sendObjects(const sp<BitTube>& tube,
T const* events, size_t count) {
return sendObjects(tube, events, count, sizeof(T));
}
// receive objects (sized blobs). If the receiving buffer isn't large enough,
// excess messages are silently discarded.
template <typename T>
static ssize_t recvObjects(const sp<BitTube>& tube,
T* events, size_t count) {
return recvObjects(tube, events, count, sizeof(T));
}
// parcels this BitTube
status_t writeToParcel(Parcel* reply) const;
.....
static ssize_t sendObjects(const sp<BitTube>& tube,
void const* events, size_t count, size_t objSize);
static ssize_t recvObjects(const sp<BitTube>& tube,
void* events, size_t count, size_t objSize);
};
// ----------------------------------------------------------------------------
};
类BitTube中sendObject、srecvObjects的实现:
ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
void const* events, size_t count, size_t objSize)
{
const char* vaddr = reinterpret_cast<const char*>(events);
ssize_t size = tube->write(vaddr, count*objSize);
// should never happen because of SOCK_SEQPACKET
LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
"BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)",
count, objSize, size);
//ALOGE_IF(size<0, "error %d sending %d events", size, count);
return size < 0 ? size : size / static_cast<ssize_t>(objSize);
}
ssize_t BitTube::recvObjects(const sp<BitTube>& tube,
void* events, size_t count, size_t objSize)
{
char* vaddr = reinterpret_cast<char*>(events);
ssize_t size = tube->read(vaddr, count*objSize);
// should never happen because of SOCK_SEQPACKET
LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
"BitTube::recvObjects(count=%zu, size=%zu), res=%zd (partial events were received!)",
count, objSize, size);
//ALOGE_IF(size<0, "error %d receiving %d events", size, count);
return size < 0 ? size : size / static_cast<ssize_t>(objSize);
}
注意当调用recvObjects后就会唤醒threadLoop线程,并且调用handleEvent函数,在sendObject、srecvObjects就会调用tube->read,tube->write函数,read,write函数实现如下:
ssize_t BitTube::write(void const* vaddr, size_t size)
{
ssize_t err, len;
do {
len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
// cannot return less than size, since we're using SOCK_SEQPACKET
err = len < 0 ? errno : 0;
} while (err == EINTR);
return err == 0 ? len : -err;
}
ssize_t BitTube::read(void* vaddr, size_t size)
{
ssize_t err, len;
do {
len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT);
err = len < 0 ? errno : 0;
} while (err == EINTR);
if (err == EAGAIN || err == EWOULDBLOCK) {
// EAGAIN means that we have non-blocking I/O but there was
// no data to be read. Nothing the client should care about.
return 0;
}
return err == 0 ? len : -err;
}
在write和read接口中将会调用原生的send和recv套接字接口,而服务端(server)监测到的数据通过BitTube发送到客户端(client),客户端通过handleEvent来分发数据。client端的handleEvent实现如下:
文件:frameworks/base/core/jni/android_hardware_SensorManager.cpp
virtual int handleEvent(int fd, int events, void* data) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
.....
while ((n = q->read(buffer, 16)) > 0) {
.....
}
.....
return 1;
}
handleEvent的方法定义在Receiver类中,Receiver类的定义如下:
class Receiver : public LooperCallback {
sp<SensorEventQueue> mSensorQueue;
sp<MessageQueue> mMessageQueue;
jobject mReceiverWeakGlobal;
jfloatArray mScratch;
public:
Receiver(const sp<SensorEventQueue>& sensorQueue,
const sp<MessageQueue>& messageQueue,
jobject receiverWeak, jfloatArray scratch) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
mSensorQueue = sensorQueue;
mMessageQueue = messageQueue;
mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak);
mScratch = (jfloatArray)env->NewGlobalRef(scratch);
}
~Receiver() {
JNIEnv* env = AndroidRuntime::getJNIEnv();
env->DeleteGlobalRef(mReceiverWeakGlobal);
env->DeleteGlobalRef(mScratch);
}
sp<SensorEventQueue> getSensorEventQueue() const {
return mSensorQueue;
}
.....
private:
virtual void onFirstRef() {
LooperCallback::onFirstRef();
mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,
ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
}
virtual int handleEvent(int fd, int events, void* data) {
....
}
};
由Receiver类的定义可以看出,Receiver类继承了类LooperCallBack (这里要注意LooperCallBack机制,本文不再详细叙述),而Receiver对象如果收到Event 事件就会回调handleEvent 方法,在handleEvent
中在获取sensorqueue对象然后调用q->read(这里的q为SensorEventQueue对象)
文件:frameworks/native/libs/gui/SensorEventQueue.cpp
ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
if (mAvailable == 0) {
ssize_t err = BitTube::recvObjects(mSensorChannel,
mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
if (err < 0) {
return err;
}
mAvailable = static_cast<size_t>(err);
mConsumed = 0;
}
size_t count = min(numEvents, mAvailable);
memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));
mAvailable -= count;
mConsumed += count;
return static_cast<ssize_t>(count);
}
这里的read将会调用BitTube::recvObjects,而recvObjects又会调用tube->read,读取Event后,再把事件通过调用dispatchSensorEvent发送出去,具体如下:
if (receiverObj.get()) {
env->CallVoidMethod(receiverObj.get(),
gBaseEventQueueClassInfo.dispatchSensorEvent,
buffer[i].sensor,
mScratch,
status,
buffer[i].timestamp);
}//注意这一段仍然在handleEvent中调用
dispatchSensorEvent在JNI函数中调用,而真正的方法实现在SystemSensorManager.java中实现,java代码实现如下:
文件:frameworks/base/core/java/android/hardware/SystemSensorManager.java
protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
long timestamp) {
......
// 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);
}
mListener.onSensorChanged(t);
}
也就是说当底层调用dispatchSensorEvent方法时候,上层会回调onSensorChanged和onAccuracyChanged来将底层Sensor数据输出到应用层,也就是说到这一步就完成了底层到上层数据的传递
三、总结
通过上述的分析,我们大概知道了Senosr在整个framework 层的机制,从registerListener开始到回调onSensorChange结束,分为两步,第一、就是使能底层的sensor,创建相关的sensor线程,第二、一旦底层有sensor数据上报,server端线程则接收数据,发送给client并回调到前台UI的listener 方法。也就是说我们要写出一个Sensor的APP,只需要执行一步操作即registerListener,当然之前你必须得获得Sensor对象和创建Listner 对象,这个后面文章将会讲到。
PS:本文只是粗略的介绍了Sensor的framework框架,还有很多细节没有说明,这个只能够通过别的篇幅来说明,以下几点
可以供大家研究:
1.client端的数据是SensorService提供的,那么SensorService是在什么时候启动的?
2.server端是有线程的,那么client端有吗?有的话在哪里说明的?
参考博文:
1.http://kernel.meizu.com/android-sensor-framework.html