一、Sensor的Framework层框架
下图为sensor子系统的框架图,由图可以看出,整个Android Sensor系统主要五部分组成,包括App、framework、HAL、kernel和硬件,本文主要分析sensor framework层,以及与HAL层的数据交互等,hal层的介绍可以参考 Sensor HAL层分析。
其中sensor数据的传输,在framework中主要由client和service部分组成,service段复制从HAL层读取数据,并将数据写道管道中,client端读取管道中的数据,反馈给app层,具体框架可以下图描叙:
2.1 Client端sensor的注册以及数据监控整体框架
(1)SensorManager类
该类主要封装了Sensor相关的API,提供给APP层使用
./frameworks/base/core/java/android/hardware/SensorManager.java
(2)SystemSensorManager类
该类实现了Sensormanager控制和数据获取的逻辑控制
./frameworks/base/core/java/android/hardware/SystemSensorManager.java
(3)android_hardware_SensorManager.cpp
该文件复制java层和native层通信的JNI实现调用Native层提供的服务
./frameworks/base/core/jni/android_hardware_SensorManager.cpp
(4)SensorManager.cpp
Sensor在Native层的客户端,负责与服务端SensorService通信
frameworks/native/libs/gui/SensorManager.cpp
(5)SensorEventQueue.cpp
消息队列
./frameworks/native/libs/gui/SensorEventQueue.cpp
(6)Bittube
该类为单向字节通道,提供进程间单向数据通信功能,SensorEventConnect是基于Bittube实现的。
frameworks/native/libs/gui/BitTube.cpp
(7)下图可以描叙sensor client的框架图,其中下图可以分为两部分分析,一部分为初始化SystemSensorManager,获取SensorList列表,一部分为sensor数据的传输与监控。
2.2 sensorList获取
(1)系统开机启动时,会创建SystemSensorManager的实例,在改函数的构造函数中,主要完成以下:
a、初始化Sensor列表:调用JNI函数nativeCreate,对sensor模块进行初始化,创建了native层SensorManager的实例;
b、初始化JNI:调用JNI函数nativeClassInit进行初始化;
c、获取Sensor列表:调用JNI函数nativeGetSensorAtIndex获取sensor,并存在mFullSensorList和mHandleToSensor列表中实现注册监听器。
./frameworks/base/core/java/android/hardware/SensorManager.java
public SystemSensorManager(Context context, Looper mainLooper) {
mMainLooper = mainLooper;
mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
mContext = context;
mNativeInstance = nativeCreate(context.getOpPackageName());
synchronized(mLock) {
if (!sSensorModuleInitialized) {
sSensorModuleInitialized = true;
nativeClassInit();//调用JNI函数进行初始化
}
}
// initialize the sensor list
for (int index = 0;;++index) {//获取sensorList
Sensor sensor = new Sensor();
if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break;
mFullSensorsList.add(sensor);
mHandleToSensor.append(sensor.getHandle(), sensor);
}
}
./frameworks/base/core/jni/android_hardware_SensorManager.cpp
static jlong nativeCreate(JNIEnv *env, jclass clazz, jstring opPackageName)
{
ScopedUtfChars opPackageNameUtf(env, opPackageName);
//创建native层的SensorManager,最终调用SensorManager的assertStateLocked()
return (jlong) new SensorManager(String16(opPackageNameUtf.c_str()));
}
static void nativeClassInit (JNIEnv *_env, jclass _this)
{
jclass sensorClass = _env->FindClass("android/hardware/Sensor");
SensorOffsets& sensorOffsets = gSensorOffsets;
sensorOffsets.name = _env->GetFieldID(sensorClass, "mName", "Ljava/lang/String;");
sensorOffsets.vendor = _env->GetFieldID(sensorClass, "mVendor", "Ljava/lang/String;");
Offsets.version = _env->GetFieldID(sensorClass, "mVersion", "I");
sensorOffsets.handle = _env->GetFieldID(sensorClass, "mHandle", "I");
sensorOffsets.range = _env->GetFieldID(sensorClass, "mMaxRange", "F");
sensorOffsets.resolution = _env->GetFieldID(sensorClass, "mResolution","F");
sensorOffsets.power = _env->GetFieldID(sensorClass, "mPower", "F");
sensorOffsets.minDelay = _env->GetFieldID(sensorClass, "mMinDelay", "I");
sensorOffsets.fifoReservedEventCount =
_env->GetFieldID(sensorClass, "mFifoReservedEventCount", "I");
sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount", "I");
sensorOffsets.stringType = _env->GetFieldID(sensorClass, "mStringType", "Ljava/lang/String;");
sensorOffsets.requiredPermission = _env->GetFieldID(sensorClass, "mRequiredPermission","Ljava/lang/String;");
sensorOffsets.maxDelay = _env->GetFieldID(sensorClass, "mMaxDelay", "I");
sensorOffsets.flags = _env->GetFieldID(sensorClass, "mFlags", "I");
sensorOffsets.setType = _env->GetMethodID(sensorClass, "setType", "(I)Z");
}
static jboolean nativeGetSensorAtIndex(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensor, jint index)
{
SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
Sensor const* const* sensorList;
size_t count = mgr->getSensorList(&sensorList);//调用SensorManager的getSensorList获取sensorlist
if (size_t(index) >= count) {
return false;
}
Sensor const* const list = sensorList[index];
const SensorOffsets& sensorOffsets(gSensorOffsets);
jstring name = getInternedString(env, &list->getName());
jstring vendor = getInternedString(env, &list->getVendor());
jstring requiredPermission = getInternedString(env, &list->getRequiredPermission());
env->SetObjectField(sensor, sensorOffsets.name, name);
......
env->SetIntField(sensor, sensorOffsets.flags, list->getFlags());
if (env->CallBooleanMethod(sensor, sensorOffsets.setType, list->getType()) == JNI_FALSE) {
jstring stringType = getInternedString(env, &list->getStringType());
env->SetObjectField(sensor, sensorOffsets.stringType, stringType);
}
return true;
}
2.3 Sensor数据监控与传输
(1)app层在监控数据辩护时通常存在以下操作:
//获取指定类型的传感器对象
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
//注册监听器mSensorManager.registerListener(this, mSensor,SensorManager.SENSOR_DELAY_NORMAL);
// SENSOR_DELAY_GAME //当sensor数据变化时会调用onSensorChanged获取数据
registerListener会调用sensorManager.java的
public boolean registerListener(SensorEventListener listener, Sensor sensor,int samplingPeriodUs, Handler handler) {
int delay = getDelay(samplingPeriodUs);
return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
}
(2)由上面可以看出
registerListener最终会调用SystemSensorManager类的registerListenerImpl方法。
在registerListenerImpl中相应的sensor会被enable,会用注册线程的Looper或系统初始化线程的Looper来
循环等待SensorEvent时间,并读取来自服务端的数据。
接着实例化SensorEventQueue,通过Jni函数nativeBaseEventQueue来创建消息队列,JNI会调用Native的
SensorManager来完成真正的创建消息队列动作。
通过实例化的SensorEventQueue添加需要监听的sensor,并对其使能和设置采样事件等。
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
synchronized (mSensorListeners) {
SensorEventQueue queue = mSensorListeners.get(listener);
//判断该listener是否被注册过,如果注册过,则存在event queue与之对应
if (queue == null) {
//第一次注册,需要创建一个event queue
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
final String fullClassName = listener.getClass().getEnclosingClass() != null ?
listener.getClass().getEnclosingClass().getName() :
listener.getClass().getName();
queue = new SensorEventQueue(listener, looper, this, fullClassName);
//将该sensor放入queue中
if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
}
//通知系统,该sensor需要进行监听
mSensorListeners.put(listener, queue);
return true;
} else {
//已有event queue ,故直接将该sensor放入queue中
return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
}
}
}
在queue.addsensor中会进行使能sensor的操作:
public boolean addSensor(
Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
// Check if already present.
int handle = sensor.getHandle();
if (mActiveSensors.get(handle)) return false;
// Get ready to receive events before calling enable.
mActiveSensors.put(handle, true);
addSensorEvent(sensor);
if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {//使能sensor,最终会调用native的enale
// Try continuous mode if batching fails.
if (maxBatchReportLatencyUs == 0 ||
maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
removeSensor(sensor, false);
return false;
}
}
return true;
}
2.4 SensorManager类
SensorManager是Sensor在native层的客户端,负责与服务端SensorService通信,在服务端sensor初始化时会调用该类的方法。
./frameworks/native/libs/gui/SensorManager.cpp
<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {
sp<SensorEventQueue> queue;
Mutex::Autolock _l(mLock);
while (assertStateLocked() == NO_ERROR) {
sp<ISensorEventConnection> connection =
mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);
if (connection == NULL) {
// SensorService just died or the app doesn't have required permissions.
ALOGE("createEventQueue: connection is NULL.");
return NULL;
}
queue = new SensorEventQueue(connection);//这里是重点,创建了数据操作的queue
break;
}
return queue;
}
SensorManager的CreateEventQueue会调用SensorEVentQueue中的函数,在SensorEVentQueue中会通过调用bitTube接口进行数据的读写操作,下面分析读取数据的流程代码,写数据的过程与读取数据的过程类似。
在读数据前先看看bitTube对象的init方法:
void BitTube::init(size_t rcvbuf, size_t sndbuf) {
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
size_t size = DEFAULT_SOCKET_BUFFER_SIZE;
setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));//创建管道
setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
// sine we don't use the "return channel", we keep it small...
setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
fcntl(sockets[0], F_SETFL, O_NONBLOCK);
fcntl(sockets[1], F_SETFL, O_NONBLOCK);
mReceiveFd = sockets[0];//返回读数据管道的套接字fd
mSendFd = sockets[1];
} else {
mReceiveFd = -errno;
ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
}
}
在这里创建了一对socketpair,分别用于读写操作,下面再看读取数据过程。
ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
if (mAvailable == 0) {
//调用bitTube的recvObjects读取读管道中的数据存放在mRecBuffer中
ssize_t err = BitTube::recvObjects(mSensorChannel,
mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
if (err < 0) {
return err;
}
mAvailable = static_cast<size_t>(err);
mConsumed = 0;
}
size_t count = min(numEvents, mAvailable);
memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));
mAvailable -= count;
mConsumed += count;
return static_cast<ssize_t>(count);
}
ssize_t BitTube::read(void* vaddr, size_t size)
{
ssize_t err, len;
do {
//以MSG_DONTWAIT方式从读管道中读取数据
len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT);
err = len < 0 ? errno : 0;
} while (err == EINTR);//信号中断,没有读取到数据
if (err == EAGAIN || err == EWOULDBLOCK) {
// EAGAIN means that we have non-blocking I/O but there was
// no data to be read. Nothing the client should care about.
return 0;
}
return err == 0 ? len : -err;
}
到这里sensor client端,从注册到数据交互都介绍完毕,下面会分析Sensor service如何与hal层交互的工作流程分析。
作者:frank_zyp
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文无所谓版权,欢迎转载。