当前位置:   article > 正文

Android Sensor (5) --SensorService和SensorManager回调原理_android sensoreventlistener什么时候回调

android sensoreventlistener什么时候回调

 

目录

1.1 FD共享流程

1.2 SensorService读取数据并且发送SensorEvent

1.3 客户端Looper收到event读取,分发给app

1.4 BitTube原理

 

SensorEvent从SensorService到SensorManager跨进程原理bitTube

 

1.1 FD共享流程

app注册listener时会初始化BaseEventQueue

  1. @frameworks/base/core/java/android/hardware/SystemSensorManager.java
  2. BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {
  3. if (packageName == null) packageName = "";
  4. nSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,
  5. new WeakReference<>(this), looper.getQueue(),
  6. packageName, mode, manager.mContext.getOpPackageName());
  7. mCloseGuard.open("dispose");
  8. mManager = manager;
  9. }
  1. @android_hardware_SensorManager.cpp
  2. {"nativeInitBaseEventQueue",
  3. "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/String;)J",
  4. (void*)nativeInitSensorEventQueue },
  5. static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
  6. jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {
  7. SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
  8. ScopedUtfChars packageUtf(env, packageName);
  9. String8 clientName(packageUtf.c_str());
  10. sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode)); //createEventQueue和SensorService连接起来
  11. sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
  12. if (messageQueue == NULL) {
  13. jniThrowRuntimeException(env, "MessageQueue is not initialized.");
  14. return 0;
  15. }
  16. sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak); //用于回调
  17. receiver->incStrong((void*)nativeInitSensorEventQueue);
  18. return jlong(receiver.get());
  19. }

//new Receiver时,使用LooperCallback addFd,把SensorService的fd共享使用looper监听起来,好回调handleEvent

  1. @frameworks/base/core/jni/android_hardware_SensorManager.cpp
  2. class Receiver : public LooperCallback {
  3. sp<SensorEventQueue> mSensorQueue;
  4. sp<MessageQueue> mMessageQueue;
  5. jobject mReceiverWeakGlobal;
  6. jfloatArray mFloatScratch;
  7. jintArray mIntScratch;
  8. public:
  9. ......
  10. private:
  11. virtual void onFirstRef() {
  12. LooperCallback::onFirstRef();
  13. mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,
  14. ALOOPER_EVENT_INPUT, this, mSensorQueue.get()); //callback:this
  15. }
  16. virtual int handleEvent(int fd, int events, void* data) {

addFd参数如下

  1. //LOOP方法定义,第4个是回调函数
  2. @system/core/libutils/Looper.cpp
  3. int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {
  4. return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);
  5. }
  6. int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {

//getFd是在SensorEventQueue初始化时候赋值

  1. @frameworks/native/libs/sensor/SensorEventQueue.cpp
  2. 49void SensorEventQueue::onFirstRef()
  3. {
  4. mSensorChannel = mSensorEventConnection->getSensorChannel();
  5. }
  6. int SensorEventQueue::getFd() const
  7. {
  8. return mSensorChannel->getFd();
  9. }

//最终调用到services中 getSensorChannel ,这个mChannel是在SensorEventConnection中初始化,然后BitTube来获取mChannel,这样就保证service和client是通一个fd

  1. @/frameworks/native/services/sensorservice/SensorEventConnection.cpp
  2. SensorService::SensorEventConnection::SensorEventConnection(
  3. const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
  4. const String16& opPackageName)
  5. : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
  6. mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
  7. mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName),
  8. mDestroyed(false) {
  9. mChannel = new BitTube(mService->mSocketBufferSize); //mChannel
  10. #if DEBUG_CONNECTIONS
  11. mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
  12. mTotalAcksNeeded = mTotalAcksReceived = 0;
  13. #endif
  14. }
  15. sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
  16. {
  17. return mChannel;
  18. }

1.2 SensorService读取数据并且发送SensorEvent

SensorService由于线程会执行threadLoop,会首先device.poll从Hal层while读取数据,然后看是不是虚拟Sensor处理,最后发送到客户端 activeConnections[i]->sendEvents

  1. bool SensorService::threadLoop() {
  2. SensorDevice& device(SensorDevice::getInstance());
  3. const int halVersion = device.getHalDeviceVersion();
  4. do {
  5. ssize_t count = device.poll(mSensorEventBuffer, numEventMax); //device.poll
  6. SortedVector< sp<SensorEventConnection> > activeConnections;
  7. populateActiveConnections(&activeConnections);
  8. // handle virtual sensors
  9. if (count && vcount) {
  10. sensors_event_t const * const event = mSensorEventBuffer;
  11. ...
  12. }
  13. //发送事件到客户端 android_hardware_SensorManager.cpp Receiver
  14. // Send our events to clients. Check the state of wake lock for each client and release the
  15. // lock if none of the clients need it.
  16. bool needsWakeLock = false;
  17. size_t numConnections = activeConnections.size();
  18. for (size_t i=0 ; i < numConnections; ++i) {
  19. if (activeConnections[i] != 0) {
  20. activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
  21. mMapFlushEventsToConnections);
  22. needsWakeLock |= activeConnections[i]->needsWakeLock();
  23. // If the connection has one-shot sensors, it may be cleaned up after first trigger.
  24. // Early check for one-shot sensors.
  25. if (activeConnections[i]->hasOneShotSensors()) {
  26. cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
  27. count);
  28. }
  29. }
  30. }
  31. } while (!Thread::exitPending());
  32. ...
  33. }

SensorService向mChannel写数据,通过BitTube完成,可以服务端写,然后通知客户端读

  1. @service/SensorEventConnection.cpp
  2. status_t SensorService::SensorEventConnection::sendEvents(
  3. sensors_event_t const* buffer, size_t numEvents,
  4. sensors_event_t* scratch,
  5. wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
  6. ...
  7. // NOTE: ASensorEvent and sensors_event_t are the same type.
  8. ssize_t size = SensorEventQueue::write(mChannel,
  9. reinterpret_cast<ASensorEvent const*>(scratch), count); //write mChannel
  10. }
  11. @frameworks/native/libs/sensor/SensorEventQueue.cpp
  12. ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
  13. ASensorEvent const* events, size_t numEvents) {
  14. return BitTube::sendObjects(tube, events, numEvents);
  15. }

1.3 客户端Looper收到event读取,分发给app

收到方法回调后,先q->read向服务端读取数据到buffer,然后通过jni调用给gBaseEventQueueClassInfo.dispatchSensorEvent

  1. @frameworks/base/core/jni/android_hardware_SensorManager.cpp
  2. virtual int handleEvent(int fd, int events, void* data) {
  3. JNIEnv* env = AndroidRuntime::getJNIEnv();
  4. sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
  5. ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
  6. ssize_t n;
  7. ASensorEvent buffer[16];
  8. while ((n = q->read(buffer, 16)) > 0) { //read
  9. if (receiverObj.get()) {
  10. env->CallVoidMethod(receiverObj.get(),
  11. gBaseEventQueueClassInfo.dispatchSensorEvent,
  12. buffer[i].sensor,
  13. mFloatScratch,
  14. status,
  15. buffer[i].timestamp);
  16. }
  17. }
  18. }
  19. mSensorQueue->sendAck(buffer, n);
  20. }
  21. return 1;
  22. }
  23. };

//gBaseEventQueueClassInfo是SystemSensorManager$BaseEventQueue

  1. gBaseEventQueueClassInfo.clazz = FindClassOrDie(env,
  2. "android/hardware/SystemSensorManager$BaseEventQueue");

SensorEventQueue继承BaseEventQueue,重写方法dispatchSensorEvent,JNI调用的就是这个方法,就可以通过mListener回调给app

  1. static final class SensorEventQueue extends BaseEventQueue {
  2. public SensorEventQueue(SensorEventListener listener, Looper looper,
  3. SystemSensorManager manager, String packageName) {
  4. super(looper, manager, OPERATING_MODE_NORMAL, packageName);
  5. mListener = listener;
  6. }
  7. protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
  8. long timestamp) {
  9. // call onAccuracyChanged() only if the value changes
  10. final int accuracy = mSensorAccuracies.get(handle);
  11. if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
  12. mSensorAccuracies.put(handle, t.accuracy);
  13. mListener.onAccuracyChanged(t.sensor, t.accuracy);
  14. }
  15. mListener.onSensorChanged(t);
  16. }
  17. }

1.4 BitTube原理

//BitTube write流程

  1. @bitTube.h
  2. static ssize_t sendObjects(const sp<BitTube>& tube,
  3. T const* events, size_t count) {
  4. return sendObjects(tube, events, count, sizeof(T));
  5. }
  6. @/frameworks/native/libs/sensor/BitTube.cpp(sensro/bitTube.h)
  7. ssize_t BitTube::sendObjects(BitTube* tube, void const* events, size_t count, size_t objSize) {
  8. const char* vaddr = reinterpret_cast<const char*>(events);
  9. ssize_t size = tube->write(vaddr, count * objSize);
  10. // should never happen because of SOCK_SEQPACKET
  11. LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
  12. "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were "
  13. "sent!)",
  14. count, objSize, size);
  15. // ALOGE_IF(size<0, "error %d sending %d events", size, count);
  16. return size < 0 ? size : size / static_cast<ssize_t>(objSize);
  17. }
  18. ssize_t BitTube::write(void const* vaddr, size_t size)
  19. {
  20. ssize_t err, len;
  21. do {
  22. len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
  23. // cannot return less than size, since we're using SOCK_SEQPACKET
  24. err = len < 0 ? errno : 0;
  25. } while (err == EINTR);
  26. return err == 0 ? len : -err;
  27. }

//BitTube read流程

  1. @SensorEventQueue.cpp
  2. ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
  3. ssize_t err = BitTube::recvObjects(mSensorChannel,
  4. mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
  5. ...
  6. }
  7. ssize_t BitTube::recvObjects(const sp<BitTube>& tube,
  8. void* events, size_t count, size_t objSize)
  9. {
  10. char* vaddr = reinterpret_cast<char*>(events);
  11. ssize_t size = tube->read(vaddr, count*objSize);
  12. ...
  13. }
  14. ssize_t BitTube::read(void* vaddr, size_t size)
  15. {
  16. ssize_t err, len;
  17. do {
  18. len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT);
  19. err = len < 0 ? errno : 0;
  20. } while (err == EINTR);
  21. }

//LoopCallBack addFd之后,会回调handEvent,handEvent里面去读Event,在发送

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/778981
推荐阅读
相关标签
  

闽ICP备14008679号