Android Sensor (5) --SensorService和SensorManager回调原理

 

目录

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

@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;
}

1.2 SensorService读取数据并且发送SensorEvent

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);
}

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

收到方法回调后,先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);
    }
}

1.4 BitTube原理

//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,在发送

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值