赞
踩
目录
1.2 SensorService读取数据并且发送SensorEvent
SensorEvent从SensorService到SensorManager跨进程原理bitTube
app注册listener时会初始化BaseEventQueue
- @frameworks/base/core/java/android/hardware/SystemSensorManager.java
- BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {
- if (packageName == null) packageName = "";
- nSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,
- new WeakReference<>(this), looper.getQueue(),
- packageName, mode, manager.mContext.getOpPackageName());
- mCloseGuard.open("dispose");
- mManager = manager;
- }
- @android_hardware_SensorManager.cpp
- {"nativeInitBaseEventQueue",
- "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/String;)J",
- (void*)nativeInitSensorEventQueue },
-
- static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
- jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {
- SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
- ScopedUtfChars packageUtf(env, packageName);
- String8 clientName(packageUtf.c_str());
- sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode)); //createEventQueue和SensorService连接起来
-
- sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
- if (messageQueue == NULL) {
- jniThrowRuntimeException(env, "MessageQueue is not initialized.");
- return 0;
- }
-
- sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak); //用于回调
- receiver->incStrong((void*)nativeInitSensorEventQueue);
- return jlong(receiver.get());
- }
//new Receiver时,使用LooperCallback addFd,把SensorService的fd共享使用looper监听起来,好回调handleEvent
- @frameworks/base/core/jni/android_hardware_SensorManager.cpp
- class Receiver : public LooperCallback {
- sp<SensorEventQueue> mSensorQueue;
- sp<MessageQueue> mMessageQueue;
- jobject mReceiverWeakGlobal;
- jfloatArray mFloatScratch;
- jintArray mIntScratch;
- public:
- ......
- private:
- virtual void onFirstRef() {
- LooperCallback::onFirstRef();
- mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,
- ALOOPER_EVENT_INPUT, this, mSensorQueue.get()); //callback:this
- }
-
- virtual int handleEvent(int fd, int events, void* data) {
addFd参数如下
- //LOOP方法定义,第4个是回调函数
- @system/core/libutils/Looper.cpp
- int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {
- return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);
- }
-
- int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {
//getFd是在SensorEventQueue初始化时候赋值
- @frameworks/native/libs/sensor/SensorEventQueue.cpp
- 49void SensorEventQueue::onFirstRef()
- {
- mSensorChannel = mSensorEventConnection->getSensorChannel();
- }
-
- int SensorEventQueue::getFd() const
- {
- return mSensorChannel->getFd();
- }
//最终调用到services中 getSensorChannel ,这个mChannel是在SensorEventConnection中初始化,然后BitTube来获取mChannel,这样就保证service和client是通一个fd
- @/frameworks/native/services/sensorservice/SensorEventConnection.cpp
- SensorService::SensorEventConnection::SensorEventConnection(
- const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
- const String16& opPackageName)
- : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
- mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
- mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName),
- mDestroyed(false) {
- mChannel = new BitTube(mService->mSocketBufferSize); //mChannel
- #if DEBUG_CONNECTIONS
- mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
- mTotalAcksNeeded = mTotalAcksReceived = 0;
- #endif
- }
-
- sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
- {
- return mChannel;
- }
SensorService由于线程会执行threadLoop,会首先device.poll从Hal层while读取数据,然后看是不是虚拟Sensor处理,最后发送到客户端 activeConnections[i]->sendEvents
- bool SensorService::threadLoop() {
- SensorDevice& device(SensorDevice::getInstance());
- const int halVersion = device.getHalDeviceVersion();
- do {
- ssize_t count = device.poll(mSensorEventBuffer, numEventMax); //device.poll
-
- SortedVector< sp<SensorEventConnection> > activeConnections;
- populateActiveConnections(&activeConnections);
-
- // handle virtual sensors
- if (count && vcount) {
- sensors_event_t const * const event = mSensorEventBuffer;
- ...
- }
-
- //发送事件到客户端 android_hardware_SensorManager.cpp Receiver
- // 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) {
- activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
- mMapFlushEventsToConnections);
- needsWakeLock |= activeConnections[i]->needsWakeLock();
- // If the connection has one-shot sensors, it may be cleaned up after first trigger.
- // Early check for one-shot sensors.
- if (activeConnections[i]->hasOneShotSensors()) {
- cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
- count);
- }
- }
- }
-
- } while (!Thread::exitPending());
- ...
- }
SensorService向mChannel写数据,通过BitTube完成,可以服务端写,然后通知客户端读
- @service/SensorEventConnection.cpp
- status_t SensorService::SensorEventConnection::sendEvents(
- sensors_event_t const* buffer, size_t numEvents,
- sensors_event_t* scratch,
- wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
- ...
- // NOTE: ASensorEvent and sensors_event_t are the same type.
- ssize_t size = SensorEventQueue::write(mChannel,
- reinterpret_cast<ASensorEvent const*>(scratch), count); //write mChannel
- }
-
- @frameworks/native/libs/sensor/SensorEventQueue.cpp
- ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
- ASensorEvent const* events, size_t numEvents) {
- return BitTube::sendObjects(tube, events, numEvents);
- }
收到方法回调后,先q->read向服务端读取数据到buffer,然后通过jni调用给gBaseEventQueueClassInfo.dispatchSensorEvent
- @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));
-
- ssize_t n;
- ASensorEvent buffer[16];
- while ((n = q->read(buffer, 16)) > 0) { //read
- if (receiverObj.get()) {
- env->CallVoidMethod(receiverObj.get(),
- gBaseEventQueueClassInfo.dispatchSensorEvent,
- buffer[i].sensor,
- mFloatScratch,
- status,
- buffer[i].timestamp);
- }
- }
-
- }
- mSensorQueue->sendAck(buffer, n);
- }
-
- return 1;
- }
- };
//gBaseEventQueueClassInfo是SystemSensorManager$BaseEventQueue
- gBaseEventQueueClassInfo.clazz = FindClassOrDie(env,
- "android/hardware/SystemSensorManager$BaseEventQueue");
SensorEventQueue继承BaseEventQueue,重写方法dispatchSensorEvent,JNI调用的就是这个方法,就可以通过mListener回调给app
- static final class SensorEventQueue extends BaseEventQueue {
- public SensorEventQueue(SensorEventListener listener, Looper looper,
- SystemSensorManager manager, String packageName) {
- super(looper, manager, OPERATING_MODE_NORMAL, packageName);
- mListener = listener;
- }
- 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);
- }
- }
//BitTube write流程
- @bitTube.h
- static ssize_t sendObjects(const sp<BitTube>& tube,
- T const* events, size_t count) {
- return sendObjects(tube, events, count, sizeof(T));
- }
-
- @/frameworks/native/libs/sensor/BitTube.cpp(sensro/bitTube.h)
- ssize_t BitTube::sendObjects(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::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;
- }
//BitTube read流程
- @SensorEventQueue.cpp
- ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
- ssize_t err = BitTube::recvObjects(mSensorChannel,
- mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
- ...
- }
-
- 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);
- ...
- }
-
- 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);
-
- }
//LoopCallBack addFd之后,会回调handEvent,handEvent里面去读Event,在发送
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。