目录
1.2 SensorService读取数据并且发送SensorEvent
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,在发送