WUCANADA / gyro / Android sensor架构(二)SystemSensorMan...

0 0

   

Android sensor架构(二)SystemSensorManager以及JNI、sensorService(and5.1)

2018-06-26  WUCANADA

第一节我们分析到应用调用SensorManager最后是调用了SystemSensorManager中,但是其是SensorManager的子类,因此可以调用父类的接口最后到子类的实现中,我们先看下其构造函数:

一、SystemSensorManager的初始化


  1. public SystemSensorManager(Context context, Looper mainLooper) {  
  2.     mMainLooper = mainLooper;//这边的mainLooper是应用主线程的looper  
  3.     mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;  
  4.     synchronized(sSensorModuleLock) {  
  5.         if (!sSensorModuleInitialized) {  
  6.             sSensorModuleInitialized = true;  
  7.   
  8.             nativeClassInit();//native方法  
  9.   
  10.             // initialize the sensor list  
  11.             final ArrayList<Sensor> fullList = sFullSensorsList;//sFullSensorsList是一个静态变量,保存所有的sensor  
  12.             int i = 0;  
  13.             do {  
  14.                 Sensor sensor = new Sensor();//新建一个sensor  
  15.                 i = nativeGetNextSensor(sensor, i);//传到JNI层,把sensor的信息补全  
  16.                 if (i>=0) {  
  17.                     //Log.d(TAG, "found sensor: " + sensor.getName() +  
  18.                     //        ", handle=" + sensor.getHandle());  
  19.                     fullList.add(sensor);  
  20.                     sHandleToSensor.append(sensor.getHandle(), sensor);  
  21.                 }  
  22.             } while (i>0);  
  23.         }  
  24.     }  
  25. }  

我们先来看下nativeClassInit方法,这个方法是在文件android_hardware_SensorManager.cpp文件中

  1. static void  
  2. nativeClassInit (JNIEnv *_env, jclass _this)  
  3. {  
  4.     jclass sensorClass = _env->FindClass("android/hardware/Sensor");  
  5.     SensorOffsets& sensorOffsets = gSensorOffsets;  
  6.     sensorOffsets.name        = _env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;");  
  7.     sensorOffsets.vendor      = _env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");  
  8.     sensorOffsets.version     = _env->GetFieldID(sensorClass, "mVersion",   "I");  
  9.     sensorOffsets.handle      = _env->GetFieldID(sensorClass, "mHandle",    "I");  
  10.     sensorOffsets.type        = _env->GetFieldID(sensorClass, "mType",      "I");  
  11.     sensorOffsets.range       = _env->GetFieldID(sensorClass, "mMaxRange",  "F");  
  12.     sensorOffsets.resolution  = _env->GetFieldID(sensorClass, "mResolution","F");  
  13.     sensorOffsets.power       = _env->GetFieldID(sensorClass, "mPower",     "F");  
  14.     sensorOffsets.minDelay    = _env->GetFieldID(sensorClass, "mMinDelay",  "I");  
  15.     sensorOffsets.fifoReservedEventCount =  
  16.             _env->GetFieldID(sensorClass, "mFifoReservedEventCount",  "I");  
  17.     sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount",  "I");  
  18.     sensorOffsets.stringType = _env->GetFieldID(sensorClass, "mStringType", "Ljava/lang/String;");  
  19.     sensorOffsets.requiredPermission = _env->GetFieldID(sensorClass, "mRequiredPermission",  
  20.                                                         "Ljava/lang/String;");  
  21.     sensorOffsets.maxDelay    = _env->GetFieldID(sensorClass, "mMaxDelay",  "I");  
  22.     sensorOffsets.flags = _env->GetFieldID(sensorClass, "mFlags",  "I");  
  23. }  

我们看这个方法,其主要是找到java层Sensor这个类的成员变量的FileId而已。

再来看看nativeGetNextSensor方法

  1. static jint  
  2. nativeGetNextSensor(JNIEnv *env, jclass clazz, jobject sensor, jint next)  
  3. {  
  4.     SensorManager& mgr(SensorManager::getInstance());  
  5.   
  6.     Sensor const* const* sensorList;  
  7.     size_t count = mgr.getSensorList(&sensorList);//获取到sensor的列表  
  8.     if (size_t(next) >= count)  
  9.         return -1;  
  10.   
  11.     Sensor const* const list = sensorList[next];  
  12.     const SensorOffsets& sensorOffsets(gSensorOffsets);  
  13.     jstring name = env->NewStringUTF(list->getName().string());  
  14.     jstring vendor = env->NewStringUTF(list->getVendor().string());  
  15.     jstring stringType = env->NewStringUTF(list->getStringType().string());  
  16.     jstring requiredPermission = env->NewStringUTF(list->getRequiredPermission().string());  
  17.     env->SetObjectField(sensor, sensorOffsets.name,      name);  
  18.     env->SetObjectField(sensor, sensorOffsets.vendor,    vendor);  
  19.     env->SetIntField(sensor, sensorOffsets.version,      list->getVersion());  
  20.     env->SetIntField(sensor, sensorOffsets.handle,       list->getHandle());  
  21.     env->SetIntField(sensor, sensorOffsets.type,         list->getType());  
  22.     env->SetFloatField(sensor, sensorOffsets.range,      list->getMaxValue());  
  23.     env->SetFloatField(sensor, sensorOffsets.resolution, list->getResolution());  
  24.     env->SetFloatField(sensor, sensorOffsets.power,      list->getPowerUsage());  
  25.     env->SetIntField(sensor, sensorOffsets.minDelay,     list->getMinDelay());  
  26.     env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount,  
  27.                      list->getFifoReservedEventCount());  
  28.     env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount,  
  29.                      list->getFifoMaxEventCount());  
  30.     env->SetObjectField(sensor, sensorOffsets.stringType, stringType);  
  31.     env->SetObjectField(sensor, sensorOffsets.requiredPermission,  
  32.                         requiredPermission);  
  33.     env->SetIntField(sensor, sensorOffsets.maxDelay, list->getMaxDelay());  
  34.     env->SetIntField(sensor, sensorOffsets.flags, list->getFlags());  
  35.     next++;  
  36.     return size_t(next) < count ? next : 0;  
  37. }  

上面的函数获取到sensormanager.cpp的sensor列表,然后把上层传下来的sensor信息补全。

我们来看下SensorManager::getSensorList函数:

  1. ssize_t SensorManager::getSensorList(Sensor const* const** list) const  
  2. {  
  3.     Mutex::Autolock _l(mLock);  
  4.     status_t err = assertStateLocked();  
  5.     if (err < 0) {  
  6.         return ssize_t(err);  
  7.     }  
  8.     *list = mSensorList;  
  9.     return mSensors.size();  
  10. }  
其将mSensorList返回,而这个对象在assertStateLocked函数中赋值,assertStateLocked函数又是在SensorManager的构造函数中直接调用

  1. status_t SensorManager::assertStateLocked() const {  
  2.     if (mSensorServer == NULL) {  
  3.         // try for one second  
  4.         const String16 name("sensorservice");  
  5.         for (int i=0 ; i<4 ; i++) {  
  6.             status_t err = getService(name, &mSensorServer);  
  7.             if (err == NAME_NOT_FOUND) {  
  8.                 usleep(250000);  
  9.                 continue;  
  10.             }  
  11.             if (err != NO_ERROR) {  
  12.                 return err;  
  13.             }  
  14.             break;  
  15.         }  
  16.   
  17.         class DeathObserver : public IBinder::DeathRecipient {  
  18.             SensorManager& mSensorManger;  
  19.             virtual void binderDied(const wp<IBinder>& who) {  
  20.                 ALOGW("sensorservice died [%p]", who.unsafe_get());  
  21.                 mSensorManger.sensorManagerDied();  
  22.             }  
  23.         public:  
  24.             DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }  
  25.         };  
  26.   
  27.         mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));  
  28.         mSensorServer->asBinder()->linkToDeath(mDeathObserver);  
  29.   
  30.         mSensors = mSensorServer->getSensorList();//调用了SensorService的getSensorList方法  
  31.         size_t count = mSensors.size();  
  32.         mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));  
  33.         for (size_t i=0 ; i<count ; i++) {  
  34.             mSensorList[i] = mSensors.array() + i;  
  35.         }  
  36.     }  
  37.   
  38.     return NO_ERROR;  
  39. }  

最后是调用了SensorService的getSensorList方法

  1. Vector<Sensor> SensorService::getSensorList()  
  2. {  
  3.     char value[PROPERTY_VALUE_MAX];  
  4.     property_get("debug.sensors", value, "0");  
  5.     const Vector<Sensor>& initialSensorList = (atoi(value)) ?  
  6.             mUserSensorListDebug : mUserSensorList;  
  7.     Vector<Sensor> accessibleSensorList;  
  8.     for (size_t i = 0; i < initialSensorList.size(); i++) {  
  9.         Sensor sensor = initialSensorList[i];  
  10.         if (canAccessSensor(sensor)) {  
  11.             accessibleSensorList.add(sensor);  
  12.         } else {  
  13.             String8 infoMessage;  
  14.             infoMessage.appendFormat(  
  15.                     "Skipped sensor %s because it requires permission %s",  
  16.                     sensor.getName().string(),  
  17.                     sensor.getRequiredPermission().string());  
  18.             ALOGI(infoMessage.string());  
  19.         }  
  20.     }  
  21.     return accessibleSensorList;  
  22. }  

getSensorList中主要是将mUserSensorListDebug , mUserSensorList中的sensor拿出来返回

这两个列表主要在onFirstRef中添加,这个函数在对象实例化的时候就调用了。

  1. void SensorService::onFirstRef() {  
  2.   
  3. .......  
  4.  mUserSensorList = mSensorList;  
  5.   
  6.             if (hasGyro) {  
  7.                 Sensor aSensor;  
  8.   
  9.                 // Add Android virtual sensors if they're not already  
  10.                 // available in the HAL  
  11.   
  12.                 aSensor = registerVirtualSensor( new RotationVectorSensor() );  
  13.                 if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {  
  14.                     mUserSensorList.add(aSensor);  
  15.                 }  
  16.   
  17.                 aSensor = registerVirtualSensor( new GravitySensor(list, count) );  
  18.                 if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {  
  19.                     mUserSensorList.add(aSensor);  
  20.                 }  
  21.   
  22.                 aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );  
  23.                 if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {  
  24.                     mUserSensorList.add(aSensor);  
  25.                 }  
  26.   
  27.                 aSensor = registerVirtualSensor( new OrientationSensor() );  
  28.                 if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {  
  29.                     // if we are doing our own rotation-vector, also add  
  30.                     // the orientation sensor and remove the HAL provided one.  
  31.                     mUserSensorList.replaceAt(aSensor, orientationIndex);  
  32. }  

这样就把上层传下来的sensor的信息补全了,最后SystemSensorManager把所有的sensor信息保存起来。


二、SystemSensorManager的注册Listener

接下来就是调用registerListener来注册监听了,最终会调用到SystemSensorManager中的registerListenerImpl接口。

  1. /** @hide */  
  2. @Override  
  3. protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,  
  4.         int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {  
  5.     if (listener == null || sensor == null) {  
  6.         Log.e(TAG, "sensor or listener is null");  
  7.         return false;  
  8.     }  
  9.     // Trigger Sensors should use the requestTriggerSensor call.  
  10.     if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {  
  11.         Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");  
  12.         return false;  
  13.     }  
  14.     if (maxBatchReportLatencyUs < 0 || delayUs < 0) {  
  15.         Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative");  
  16.         return false;  
  17.     }  
  18.   
  19.     // Invariants to preserve:  
  20.     // - one Looper per SensorEventListener  
  21.     // - one Looper per SensorEventQueue  
  22.     // We map SensorEventListener to a SensorEventQueue, which holds the looper  
  23.     synchronized (mSensorListeners) {  
  24.         SensorEventQueue queue = mSensorListeners.get(listener);  
  25.         if (queue == null) {  
  26.             Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;  
  27.             queue = new SensorEventQueue(listener, looper, this);//新建SensorEventQueue  
  28.             if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) {  
  29.                 queue.dispose();  
  30.                 return false;  
  31.             }  
  32.             mSensorListeners.put(listener, queue);  
  33.             return true;  
  34.         } else {  
  35.             return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags);  
  36.         }  
  37.     }  
  38. }  

先去从mSensorListeners中查找listenr的SensorEventQueue,没有新建一个,有的话加入注册的sensor。我们先来看下SensorEventQueue的构造函数:

  1. static final class SensorEventQueue extends BaseEventQueue {  
  2.     private final SensorEventListener mListener;  
  3.     private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();  
  4.   
  5.     public SensorEventQueue(SensorEventListener listener, Looper looper,  
  6.             SystemSensorManager manager) {  
  7.         super(looper, manager);  
  8.         mListener = listener;  
  9.     }  

其构造函数没有什么特别的,再来看下其父类的BaseEventQueue 的构造函数:

  1. BaseEventQueue(Looper looper, SystemSensorManager manager) {  
  2.     nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch);  
  3.     mCloseGuard.open("dispose");  
  4.     mManager = manager;  
  5. }  

其调用了nativeInitBaseEventQueue的jni函数:

  1. static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQ, jobject msgQ, jfloatArray scratch) {  
  2.     SensorManager& mgr(SensorManager::getInstance());  
  3.     sp<SensorEventQueue> queue(mgr.createEventQueue());//在SensorManager中建一个SensorEventQueue  
  4.   
  5.     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);  
  6.     if (messageQueue == NULL) {  
  7.         jniThrowRuntimeException(env, "MessageQueue is not initialized.");  
  8.         return 0;  
  9.     }  
  10.   
  11.     sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQ, scratch);//新建一个Receiver  
  12.     receiver->incStrong((void*)nativeInitSensorEventQueue);  
  13.     return jlong(receiver.get());  
  14. }  

新建一个Receiver,传入一个SensorEventQueue和MessageQueue,MessageQueue是上层传下来的。


三、Receiver将应用fd加入looper

我们再来看看Receiver的构造函数:

  1. Receiver(const sp<SensorEventQueue>& sensorQueue,  
  2.         const sp<MessageQueue>& messageQueue,  
  3.         jobject receiverObject, jfloatArray scratch) {  
  4.     JNIEnv* env = AndroidRuntime::getJNIEnv();  
  5.     mSensorQueue = sensorQueue;  
  6.     mMessageQueue = messageQueue;  
  7.     mReceiverObject = env->NewGlobalRef(receiverObject);  
  8.     mScratch = (jfloatArray)env->NewGlobalRef(scratch);  
  9. }  

再来看看onFirstRef函数,是将上层传下来的MessageQueue中的looper加入了SensorEventQueue的fd,并且Receiver这个类是继承了public LooperCallback,也就是它实现了handleEvent函数,来实现looper中的epoll的回调,这个具体在按键流程中详细介绍过,这里就不再左介绍了。

  1. virtual void onFirstRef() {  
  2.     LooperCallback::onFirstRef();  
  3.     mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,  
  4.             ALOOPER_EVENT_INPUT, this, mSensorQueue.get());  
  5. }  

那我们再来看看SensorEventQueue的创建,是调用了SensorManager的createEventQueue方法:

  1. sp<SensorEventQueue> SensorManager::createEventQueue()  
  2. {  
  3.     sp<SensorEventQueue> queue;  
  4.   
  5.     Mutex::Autolock _l(mLock);  
  6.     while (assertStateLocked() == NO_ERROR) {  
  7.         sp<ISensorEventConnection> connection =  
  8.                 mSensorServer->createSensorEventConnection();//调用了SensorService的createSensorEventConnection  
  9.         if (connection == NULL) {  
  10.             // SensorService just died.  
  11.             ALOGE("createEventQueue: connection is NULL. SensorService died.");  
  12.             continue;  
  13.         }  
  14.         queue = new SensorEventQueue(connection);  
  15.         break;  
  16.     }  
  17.     return queue;  
  18. }  

这个函数中调用了SensorService的createSensorEventConnection方法返回一个Connection,然后作为入参构造了SensorEventQueue对象,

先来看下SensorEventQueue对象

  1. SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)  
  2.     : mSensorEventConnection(connection), mRecBuffer(NULL), mAvailable(0), mConsumed(0),  
  3.       mNumAcksToSend(0) {  
  4.     mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];  
  5. }  
  6.   
  7. SensorEventQueue::~SensorEventQueue() {  
  8.     delete [] mRecBuffer;  
  9. }  
  10.   
  11. void SensorEventQueue::onFirstRef()  
  12. {  
  13.     mSensorChannel = mSensorEventConnection->getSensorChannel();  
  14. }  
  15.   
  16. int SensorEventQueue::getFd() const  
  17. {  
  18.     return mSensorChannel->getFd();  
  19. }  

最后还是调了connection才能调用到getFd。我们来看下SensorService的createSensorEventConnection函数返回的connection

  1. sp<ISensorEventConnection> SensorService::createSensorEventConnection()  
  2. {  
  3.     uid_t uid = IPCThreadState::self()->getCallingUid();  
  4.     sp<SensorEventConnection> result(new SensorEventConnection(this, uid));  
  5.     return result;  
  6. }  

再来看SensorEventConnection的构造函数,其mChannel的一个BitTube对象

  1. SensorService::SensorEventConnection::SensorEventConnection(  
  2.         const sp<SensorService>& service, uid_t uid)  
  3.     : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),  
  4.       mDead(false), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0) {  
  5.     mChannel = new BitTube(mService->mSocketBufferSize);  
  6. #if DEBUG_CONNECTIONS  
  7.     mEventsReceived = mEventsSentFromCache = mEventsSent = 0;  
  8.     mTotalAcksNeeded = mTotalAcksReceived = 0;  
  9. #endif  
  10. }  

我们再看BitTube对象

  1. BitTube::BitTube()  
  2.     : mSendFd(-1), mReceiveFd(-1)  
  3. {  
  4.     init(DEFAULT_SOCKET_BUFFER_SIZE, DEFAULT_SOCKET_BUFFER_SIZE);  
  5. }  
  6.   
  7. BitTube::BitTube(size_t bufsize)  
  8.     : mSendFd(-1), mReceiveFd(-1)  
  9. {  
  10.     init(bufsize, bufsize);  
  11. }  
  12.   
  13. BitTube::BitTube(const Parcel& data)  
  14.     : mSendFd(-1), mReceiveFd(-1)  
  15. {  
  16.     mReceiveFd = dup(data.readFileDescriptor());  
  17.     if (mReceiveFd < 0) {  
  18.         mReceiveFd = -errno;  
  19.         ALOGE("BitTube(Parcel): can't dup filedescriptor (%s)",  
  20.                 strerror(-mReceiveFd));  
  21.     }  
  22. }  
  23.   
  24. BitTube::~BitTube()  
  25. {  
  26.     if (mSendFd >= 0)  
  27.         close(mSendFd);  
  28.   
  29.     if (mReceiveFd >= 0)  
  30.         close(mReceiveFd);  
  31. }  
  32.   
  33. void BitTube::init(size_t rcvbuf, size_t sndbuf) {  
  34.     int sockets[2];  
  35.     if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {  
  36.         size_t size = DEFAULT_SOCKET_BUFFER_SIZE;  
  37.         setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));  
  38.         setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));  
  39.         // sine we don't use the "return channel", we keep it small...  
  40.         setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));  
  41.         setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));  
  42.         fcntl(sockets[0], F_SETFL, O_NONBLOCK);  
  43.         fcntl(sockets[1], F_SETFL, O_NONBLOCK);  
  44.         mReceiveFd = sockets[0];  
  45.         mSendFd = sockets[1];  
  46.     } else {  
  47.         mReceiveFd = -errno;  
  48.         ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));  
  49.     }  
  50. }  

我们看到在init中创建一个一对socketpair,一个给mReceiveFd,另一个给mSendFd。和按键流程很像吧。

getFd返回就是mReceiveFd

  1. int BitTube::getFd() const  
  2. {  
  3.     return mReceiveFd;  
  4. }  

这样就很清晰了,SensorService中有sensor数据到来的时候,发送数据的时候利用上面的sendFd来发送数据,这样mReceiveFd就有数据,这样Looper的epoll就唤醒,调用了注册的回调handEvent函数,然后再到上层。但有没有觉得很奇怪,SensorService没有保存sendFd。我们来看刚那个函数:

  1. sp<ISensorEventConnection> SensorService::createSensorEventConnection()  
  2. {  
  3.     uid_t uid = IPCThreadState::self()->getCallingUid();  
  4.     sp<SensorEventConnection> result(new SensorEventConnection(this, uid));  
  5.     return result;  
  6. }  

这个后面详细再说。


四、Receiver的回调

我们再来看看Receiver的回调handleEvent函数

  1. virtual int handleEvent(int fd, int events, void* data) {  
  2.     JNIEnv* env = AndroidRuntime::getJNIEnv();  
  3.     sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);  
  4.     ssize_t n;  
  5.     ASensorEvent buffer[16];  
  6.     while ((n = q->read(buffer, 16)) > 0) {  
  7.         for (int i=0 ; i<n ; i++) {  
  8.             if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {  
  9.                 // step-counter returns a uint64, but the java API only deals with floats  
  10.                 float value = float(buffer[i].u64.step_counter);  
  11.                 env->SetFloatArrayRegion(mScratch, 0, 1, &value);  
  12.             } else {  
  13.                 env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);  
  14.             }  
  15.   
  16.             if (buffer[i].type == SENSOR_TYPE_META_DATA) {  
  17.                 // This is a flush complete sensor event. Call dispatchFlushCompleteEvent  
  18.                 // method.  
  19.                 env->CallVoidMethod(mReceiverObject,  
  20.                                     gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,  
  21.                                     buffer[i].meta_data.sensor);  
  22.             } else {  
  23.                 int8_t status;  
  24.                 switch (buffer[i].type) {  
  25.                 case SENSOR_TYPE_ORIENTATION:  
  26.                 case SENSOR_TYPE_MAGNETIC_FIELD:  
  27.                 case SENSOR_TYPE_ACCELEROMETER:  
  28.                 case SENSOR_TYPE_GYROSCOPE:  
  29.                     status = buffer[i].vector.status;  
  30.                     break;  
  31.                 case SENSOR_TYPE_HEART_RATE:  
  32.                     status = buffer[i].heart_rate.status;  
  33.                     break;  
  34.                 default:  
  35.                     status = SENSOR_STATUS_ACCURACY_HIGH;  
  36.                     break;  
  37.                 }  
  38.                 env->CallVoidMethod(mReceiverObject,  
  39.                                     gBaseEventQueueClassInfo.dispatchSensorEvent,  
  40.                                     buffer[i].sensor,  
  41.                                     mScratch,  
  42.                                     status,  
  43.                                     buffer[i].timestamp);  
  44.             }  
  45.             if (env->ExceptionCheck()) {  
  46.                 mSensorQueue->sendAck(buffer, n);  
  47.                 ALOGE("Exception dispatching input event.");  
  48.                 return 1;  
  49.             }  
  50.         }  
  51.         mSensorQueue->sendAck(buffer, n);//给SensorService返回信息  
  52.     }  
  53.     if (n<0 && n != -EAGAIN) {  
  54.         // FIXME: error receiving events, what to do in this case?  
  55.     }  
  56.     return 1;  
  57. }  

当有数据过来的时候调用上面的java层的dispatchSensorEvent函数,最后sendAck返回信息给SensorService,也是SensorEventQueue中的mReceiveFd发送。

我们再来看看java层的dispatchSensorEvent函数:

  1. protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,  
  2.         long timestamp) {  
  3.     final Sensor sensor = sHandleToSensor.get(handle);  
  4.     SensorEvent t = null;  
  5.     synchronized (mSensorsEvents) {  
  6.         t = mSensorsEvents.get(handle);  
  7.     }  
  8.   
  9.     if (t == null) {  
  10.         // This may happen if the client has unregistered and there are pending events in  
  11.         // the queue waiting to be delivered. Ignore.  
  12.         return;  
  13.     }  
  14.     // Copy from the values array.  
  15.     System.arraycopy(values, 0, t.values, 0, t.values.length);  
  16.     t.timestamp = timestamp;  
  17.     t.accuracy = inAccuracy;  
  18.     t.sensor = sensor;  
  19.   
  20.     // call onAccuracyChanged() only if the value changes  
  21.     final int accuracy = mSensorAccuracies.get(handle);  
  22.     if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {  
  23.         mSensorAccuracies.put(handle, t.accuracy);  
  24.         mListener.onAccuracyChanged(t.sensor, t.accuracy);  
  25.     }  
  26.     mListener.onSensorChanged(t);  
  27. }  

最后将数据传给应用的onSensorChanged方法。在传给应用之前,我们将数据封装成了SensorEvent,在每一个EventQueue addSensor的时候会调用addSensorEvent函数 

  1. public void addSensorEvent(Sensor sensor) {  
  2.     SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,  
  3.             mManager.mTargetSdkLevel));  
  4.     synchronized (mSensorsEvents) {  
  5.         mSensorsEvents.put(sensor.getHandle(), t);  
  6.     }  
  7. }  

最后封装SensorEvent,也从mSensorsEvents中取出来,再赋值。


五、使能Sensor

最后一个问题,是SensorService中还没有sendFd的保存,下面我们看看何时把这个fd保存在SensorService的呢?

我们先来看下BaseEventQueue的addSensor函数

  1. public boolean addSensor(  
  2.         Sensor sensor, int delayUs, int maxBatchReportLatencyUs, int reservedFlags) {  
  3.     // Check if already present.  
  4.     int handle = sensor.getHandle();  
  5.     if (mActiveSensors.get(handle)) return false;  
  6.   
  7.     // Get ready to receive events before calling enable.  
  8.     mActiveSensors.put(handle, true);//加入ActiveSensor的列表中去  
  9.     addSensorEvent(sensor);//加入  
  10.     if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags) != 0) {//调用enableSensor  
  11.         // Try continuous mode if batching fails.  
  12.         if (maxBatchReportLatencyUs == 0 ||  
  13.             maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0, 0) != 0) {  
  14.           removeSensor(sensor, false);  
  15.           return false;  
  16.         }  
  17.     }  
  18.     return true;  
  19. }  

我们再来看看enableSensor函数

  1. private int enableSensor(  
  2.         Sensor sensor, int rateUs, int maxBatchReportLatencyUs, int reservedFlags) {  
  3.     if (nSensorEventQueue == 0) throw new NullPointerException();  
  4.     if (sensor == null) throw new NullPointerException();  
  5.     return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), rateUs,  
  6.             maxBatchReportLatencyUs, reservedFlags);  
  7. }  

这个函数中又调用了nativeEnableSensor函数:

  1. static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,  
  2.                                jint maxBatchReportLatency, jint reservedFlags) {  
  3.     sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));  
  4.     return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,  
  5.                                                          reservedFlags);  
  6. }  

我们再来看看SensorEventQueue的enableSensor函数

  1. status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,  
  2.                                         int maxBatchReportLatencyUs, int reservedFlags) const {  
  3.     return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),  
  4.                                                  us2ns(maxBatchReportLatencyUs), reservedFlags);  
  5. }  

来看看connection的enableDisable函数:

  1. status_t SensorService::SensorEventConnection::enableDisable(  
  2.         int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,  
  3.         int reservedFlags)  
  4. {  
  5.     status_t err;  
  6.     if (enabled) {  
  7.         err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,  
  8.                                reservedFlags);  
  9.   
  10.     } else {  
  11.         err = mService->disable(this, handle);  
  12.     }  
  13.     return err;  
  14. }  

又调用了SensorService的enable函数,将Connection加入mActiveConnections

  1. status_t SensorService::enable(const sp<SensorEventConnection>& connection,  
  2.         int handle, nsecs_t samplingPeriodNs,  nsecs_t maxBatchReportLatencyNs, int reservedFlags)  
  3. {  
  4. .......  
  5.   
  6.     if (connection->addSensor(handle)) {  
  7.         BatteryService::enableSensor(connection->getUid(), handle);  
  8.         // the sensor was added (which means it wasn't already there)  
  9.         // so, see if this connection becomes active  
  10.         if (mActiveConnections.indexOf(connection) < 0) {  
  11.             mActiveConnections.add(connection);  
  12.         }  
  13.     }  
  14. .....  
  15. }  

而在SensorService中会在threadLoop函数中调用下面来发送数据,而下面的activeConnections就是从mActiveConnections获取的。

  1. bool needsWakeLock = false;  
  2. size_t numConnections = activeConnections.size();  
  3. for (size_t i=0 ; i < numConnections; ++i) {  
  4.     if (activeConnections[i] != 0) {  
  5.         activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,  
  6.                 mMapFlushEventsToConnections);  

最后SensorEventConnection也是调用了sendEvents,而这个函数是做了write sendFd这样的操作,然后应用进程的epoll机制唤醒,调用回调再到Receiver的handleEvent,然后再会反调Java的dispatchSensorEvent函数,最后就到应用的onSensorChanged里面了。


六|、总结

总结:这样我们就把sensor数据从SensorService到应用的onSensorChanged分析完了,至于SensorService如何获取各个sensor的数据,等等留作以后分析。



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。如发现有害或侵权内容,请点击这里 或 拨打24小时举报电话:4000070609 与我们联系。

    来自: WUCANADA > 《gyro》

    猜你喜欢

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多