MTK6580(Android6.0)-Psensor FrameWork 层分析

一、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.cpp
sendEvents中调用的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.h
 frameworks/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



  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值