第一层是应用层:代表上层使用frameworks的接口注册或使用一个sensor:
Sensor sensor = sensorManager.getDefaultSensor(sensortype);
sensorManager.registerListener(mListener, sensor, SensorManager.SENSOR_DELAY_FASTEST);
第二层Frameworks层: 包含SensorService, 接收HAl层传上来的 sensor event 数据,并让应用层做出相应的动作,如陀螺仪转动,横竖屏切换等
第三层HAL层: kernel层的硬件驱动等, 有SensorDevice 的poll函数读取数据
在android系统中每一个功能点都是由Service来调度, 如熟知的ActivityManagerService, PackageManagerService等等, 这些我会在以后的博客中逐个分析
先看调用时序图
SystemServer中唯一的一个JNI调用启动SensorService
SystemServer.java :
/**
* Start the sensor service.
*/
private static native void startSensorService();
void* sensorInit(void *arg) {
ALOGI("System server: starting sensor init.\n");
// Start the sensor service
SensorService::instantiate();
ALOGI("System server: sensor init done.\n");
return NULL;
}
使用Binder机制将SensorService启动。
SensorService的初始化:
Service的初始在SensorService::onFirstRef函数中
SensorDevice& dev(SensorDevice::getInstance()); // 实例化SensorDevice
if (dev.initCheck() == NO_ERROR) {
sensor_t const* list;
ssize_t count = dev.getSensorList(&list); // 获取sensor list
if (count > 0) {
ssize_t orientationIndex = -1;
bool hasGyro = false, hasAccel = false, hasMag = false;
... ...
mLastEventSeen.setCapacity(count);
for (ssize_t i=0 ; irun("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
run("SensorService", PRIORITY_URGENT_DISPLAY);
}
}
SensorService的初始化主要有:
1. 创建SensorDevice实例,获取Sensor列表
2. 调用SensorDevice.getSensorList(),获取Sensor模块所有传感器列表并为为每个传感器注册监听器
SensorDevice的初始化:
SensorDevice::SensorDevice()
: mSensorDevice(0),
mSensorModule(0)
{
status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
(hw_module_t const**)&mSensorModule);
if (mSensorModule) {
err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
... ...
if (mSensorDevice) {
if (mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_1 ||
mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_2) {
}
sensor_t const* list;
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
mActivationCount.setCapacity(count);
Info model;
for (size_t i=0 ; iactivate( reinterpret_cast(mSensorDevice),list[i].handle, 0);
... ...
}
SensorService 及SensorDevice的启动主要实现一下几件事:
1. 调用HAL层的hw_get_modele()方法,加载Sensor模块so文件
2. 调用sensor.h的sensors_open方法打开设备
3. 调用sensors_poll_device_t->activate()对Sensor模块使能
启动一个线程,获取HAL层的数据:
SensorService::threadLoop():
bool SensorService::threadLoop()
{
SensorDevice& device(SensorDevice::getInstance());
const size_t vcount = mVirtualSensorList.size();
const int halVersion = device.getHalDeviceVersion();
do {
ssize_t count = device.poll(mSensorEventBuffer, numEventMax); // 从HAL层读取数据
// Reset sensors_event_t.flags to zero for all events in the buffer.
for (int i = 0; i < count; i++) {
mSensorEventBuffer[i].flags = 0;
}
SortedVector< sp > activeConnections;
populateActiveConnections(&activeConnections);
... ...
// 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);
}
}
}
... ...
abort();
return false;
}
进入while循环, 不停的从底层poll数据, 并sendEvent到上层
先看服务器与客户端状态图:
1. 上图涉及两个线程:
橘黄色服务端: SensorService::threadLoop 它通过SensorDevice::poll 不停的从HAL获取数据
蓝色客户端:android_hardware_SensorManager::Receiver 从EventQueue中读数据
2. 传递数据是的一个关键宏:sensors_event_t
int32_t version; // sensor 的version
int32_t sensor; //sensor 标识每个sensor都唯一
int32_t type; // sensor 的类型一个sensor可有多个类型 如: 陀螺仪有校准后与校准前类型
int32_t reserved0;
int64_t timestamp; // sensor产生时间戳
union {
union {
float data[16];
sensors_vec_t acceleration; //加速sensor
sensors_vec_t magnetic; // 磁场感应sensor
sensors_vec_t orientation; // 横竖屏sensor
sensors_vec_t gyro; // 陀螺仪sensor
float temperature; //温度sensor
float distance; // 距离sensor
float light; // 光感sensor
float pressure; //压力sensor
float relative_humidity; // 相对湿度sensor
uncalibrated_event_t uncalibrated_gyro; // 无定向的陀螺仪sensor
uncalibrated_event_t uncalibrated_magnetic; // 无定向的磁场sensor
heart_rate_event_t heart_rate; // 心率检测sensor
meta_data_event_t meta_data;
};
union {
uint64_t data[8];
uint64_t step_counter; // 步数检测sensor
} u64;
};
uint32_t flags;
uint32_t reserved1[3];
} sensors_event_t;
4. 使用管道传递数据的原因是由于sensor数据量较大, Binder不能胜任此任务, 所以需要BitTube管道来传递这些数据
5. 数据时序图:
根据图示可以看出客户端与服务端通过Binder建立链接, 通过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]; //socket[0]接受数据
mSendFd = sockets[1]; // socket[1]发送数据
} else {
mReceiveFd = -errno;
ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
}
}
1. 使用socket[0] 来接收数据
2. 使用socket[1] 来发送数据
3.通过pipe(fds)创建管道,通过fcntl来设置操作管道的方式,设置通道两端的操作方式为O_NONBLOCK ,非阻塞IO方式,read或write调用返回-1和EAGAIN错误。