前言:

相对于其他模块, Sensor的API还是非常简洁的.对Sensor的开发也很简单。Android 6.0 系统支持的传感器

多达26种,加速度传感器 (accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、

陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和

距离传感器(proximity)等等, Sensor.java 中有相关定义。

 

服务端的代码路径如下,

frameworks\native\services\sensorservice

HAL对应的代码如下,

hardware\libhardware\include\hardware\ sensor.h

hardware\qcom\sensors

其他代码对应路径

frameworks\native\libs\gui

1,概述

Sensor架构图如下,


Android tether Android tether 服务端_客户端


主要包括2个进程,服务端和客户端。

Sensor的整体逻辑非常清晰,一个控制流,一个数据流。

 

2 sensor服务端

开始一直以为sensor服务进程向很多守护进程一样通过init.rc配置文件启动,后来才发现是通过systemserver进程启动,

并且运行于systemserver进程中,就像systemserver中的各种服务一样,只是通过C/C++实现而已。

启动流程图如下,


Android tether Android tether 服务端_Android tether_02


SystemServer对应的为com_android_server_SystemServer.cpp,其实, SystemServer中只有一个native方法,

就是startSensorService,说了这么多, com_android_server_SystemServer.cpp就是为了启动sensor服务才有的。

sensorInit方法如下,

void* sensorInit(void *arg) {
    ALOGI("System server: starting sensor init.\n");
    // Start the sensor service
    SensorService::instantiate();//new SensorService对象
    ALOGI("System server: sensor init done.\n");
    return NULL;
}

SensorService的onFirstRef方法中,主要逻辑如下,

1,获取SensorDevice对象,

SensorDevice& dev(SensorDevice::getInstance());

2, 获取Sensor列表

ssize_t count = dev.getSensorList(&list);

3,sensor注册

for (ssize_t i=0 ; i<count ; i++) {
     registerSensor( new HardwareSensor(list[i]) );

首先为每一个sensor注册一个对应的HardwareSensor。

然后对有些sensor,注册特殊的sensor,例如,

aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );

4,启动服务

mAckReceiver = new SensorEventAckReceiver(this);
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
run("SensorService", PRIORITY_URGENT_DISPLAY);

2.1初始化

流程图如下,


Android tether Android tether 服务端_android_03

SensorDevice继承于Singleton,所以整个android系统中,仅有一个SensorDevice对象,

class SensorDevice : public Singleton<SensorDevice> {
friend class Singleton<SensorDevice>;
    sensors_poll_device_1_t* mSensorDevice;
    struct sensors_module_t* mSensorModule;

SensorDevice的构造方法主要逻辑如下,

1,加载sensor模块so库

status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
            (hw_module_t const**)&mSensorModule);

并且mSensorModule变量就指向sensor模块so库。通过该变量可以调用sensor模块so库中的方法。

但是mSensorDevice又是什么呢?是sensors_poll_device_1_t对象,

sensors_poll_device_1_t在sensor.h中定义,只是一个有些方法的结构体。

 

2, 调用sensor.h的sensors_open_1方法打开设备

err = sensors_open_1(&mSensorModule->common, &mSensorDevice);

3,获取so库的Sensor列表

ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
            mActivationCount.setCapacity(count);

4,激活sensor

for (size_t i=0 ; i<size_t(count) ; i++) {
      mActivationCount.add(list[i].handle, model);
      mSensorDevice->activate(
      reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), list[i].handle, 0);
}

2.1.1 sensor模块打开

sensor.h中的sensors_open_1方法如下,

static inline int sensors_open_1(const struct hw_module_t* module,
        sensors_poll_device_1_t** device) {
    return module->methods->open(module,
            SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);
}

直接调用sensor模块的open方法,

sensors.cpp对应的open方法为open_sensors

static struct hw_module_methods_t sensors_module_methods = {
		open: open_sensors
};

在open_sensors方法中主要进行一些初始化的操作。

1,构造NativeSensorManager对象,

NativeSensorManager& sm(NativeSensorManager::getInstance());

2,构造sensors_poll_context_t,并且初始化,

sensors_poll_context_t *dev = new sensors_poll_context_t();
•••
dev->device.common.module   = const_cast<hw_module_t*>(module);
dev->device.common.close	= poll__close;
dev->device.activate		= poll__activate;
dev->device.setDelay		= poll__setDelay;
dev->device.poll		= poll__poll;
dev->device.calibrate		= poll_calibrate;

sensors_poll_context_t是sensors.cpp内部的一个结构体,类似于一个类,里面也有各种方法。

这样,sensorservice也可以通过mSensorDevice调用HAL中的方法。

 

在sensors_poll_context_t的构造方法中,对每个event创建从driver中读取数据的节点。

for (i = 0; i < number; i++) {
		context = sm.getInfoByHandle(slist[i].handle);

		mPollFds[i].fd = (context == NULL) ? -1 : context->data_fd;
		mPollFds[i].events = POLLIN;
		mPollFds[i].revents = 0;
	}
	ALOGI("The avaliable sensor handle number is %d",i);
	int wakeFds[2];
	int result = pipe(wakeFds);
	ALOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno));
	fcntl(wakeFds[0], F_SETFL, O_NONBLOCK);
	fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);
	mWritePipeFd = wakeFds[1];

	mPollFds[number].fd = wakeFds[0];
	mPollFds[number].events = POLLIN;
	mPollFds[number].revents = 0;

2.1.2 模块的Sensor列表

上层调用模块的get_sensors_list方法其实就是调用module__get_sensors_list方法,

get_sensors_list: sensors__get_sensors_list,

该方法直接调用NativeSensorManager的getSensorList方法,

static int sensors__get_sensors_list(struct sensors_module_t*, struct sensor_t const** list)
{
	NativeSensorManager& sm(NativeSensorManager::getInstance());
	return sm.getSensorList(list);
}

NativeSensorManager的getSensorList方法如下,

int NativeSensorManager::getSensorList(const sensor_t **list) {
	*list = mSensorCount ? sensor_list:NULL;
	return mSensorCount;
}

直接返回NativeSensorManager的mSensorCount变量。

mSensorCount变量的值是在NativeSensorManager的构造方法中调用getDataInfo方法赋值的。

sensor_list 变量保存各种sensor。

getDataInfo方法会为每个sensor保存对应的SensorContext结构体,

NativeSensorManager.h的SensorContext结构体定义如下,

struct SensorContext {
	char   name[SYSFS_MAXLEN]; // name of the sensor
	char   vendor[SYSFS_MAXLEN]; // vendor of the sensor
	char   enable_path[PATH_MAX]; // the control path of this sensor
	char   data_path[PATH_MAX]; // the data path to get sensor events

	struct sensor_t *sensor; // point to the sensor_t structure in the sensor list
	SensorBase     *driver; // point to the sensor driver instance

	int data_fd; // the file descriptor of the data device node
	int enable; // indicate if the sensor is enabled
	bool is_virtual; // indicate if this is a virtual sensor
	int64_t delay_ns; // the poll delay setting of this sensor
	int64_t latency_ns; // the max report latency of this sensor
	struct listnode dep_list; // the background sensor type needed for this sensor

	struct listnode listener; // the head of listeners of this sensor
};

SensorContext保存着对应sensor驱动的各种信息,读取sensor的值时会使用该结构体的data_fd变量。

2.1.3 激活Sensor

HAL 中的activate流程图如下,


Android tether Android tether 服务端_服务端_04


poll__activate直接调用sensors_poll_context_t的activate方法,

static int poll__activate(struct sensors_poll_device_t *dev,
		int handle, int enabled) {
	sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
	return ctx->activate(handle, enabled);
}

sensors_poll_context_t的activate方法首先调用NativeSensorManager.c的activate方法打开对应的驱动设备文件,

然后往里面写入值1.

int sensors_poll_context_t::activate(int handle, int enabled) {
	int err = -1;
	NativeSensorManager& sm(NativeSensorManager::getInstance());
	Mutex::Autolock _l(mLock);
	err = sm.activate(handle, enabled);
	if (enabled && !err) {
		const char wakeMessage(WAKE_MESSAGE);
		int result = write(mWritePipeFd, &wakeMessage, 1);
		ALOGE_IF(result<0, "error sending wake message (%s)", strerror(errno));
	}
	return err;
}

SensorBase.cpp的enable方法是一个虚方法,由不同的独立的sensor去实现。

例如, Accelerometer.cpp的enable方法实现如下,

strlcpy(&input_sysfs_path[input_sysfs_path_len], SYSFS_ENABLE, SYSFS_MAXLEN);
fd = open(input_sysfs_path, O_RDWR);
if (fd >= 0) {
	char buf[2];
	int err;
	buf[1] = 0;
	if (flags) {
		buf[0] = '1';
		mEnabledTime = getTimestamp() + IGNORE_EVENT_TIME;
		sysclk_sync_offset = getClkOffset();
	} else {
		buf[0] = '0';
	}
	err = write(fd, buf, sizeof(buf));
	close(fd);
	mEnabled = flags;
	return 0;
}

实际上就是获取对应加速度sensor的驱动节点路径,然后打开该路径,往里面写入2个字符。

这样,从HAL到驱动这条路就打通了。

2.2 获取sensor列表

SensorService.cpp的onFirstRef中获取sensor列表的代码如下,

sensor_t const* list;
ssize_t count = dev.getSensorList(&list);

将获取的sensor保存在list中。

SensorDevice.cpp的getSensorList方法如下,

ssize_t SensorDevice::getSensorList(sensor_t const** list) {
    if (!mSensorModule) return NO_INIT;
    ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
    return count;
}

上节中已经说明了,调用模块的get_sensors_list方法将获取的sensor保存在list中。

2.3 sensor注册

registerSensor方法如下,

Sensor SensorService::registerSensor(SensorInterface* s)
{
    sensors_event_t event;
    memset(&event, 0, sizeof(event));

    const Sensor sensor(s->getSensor());
    // add to the sensor list (returned to clients)
    mSensorList.add(sensor);
    // add to our handle->SensorInterface mapping
    mSensorMap.add(sensor.getHandle(), s);
    // create an entry in the mLastEventSeen array
    mLastEventSeen.add(sensor.getHandle(), NULL);

    return sensor;
}

实际上就是将从sensor模块获取的sensor 对象以及相关信息分别放在mSensorList, mSensorMap等数据结构中。

registerVirtualSensor也是调用registerSensor方法完成的。

Sensor SensorService::registerVirtualSensor(SensorInterface* s)
{
    Sensor sensor = registerSensor(s);
    mVirtualSensorList.add( s );
    return sensor;
}

2.4 启动服务

启动服务的代码如下,

mAckReceiver = new SensorEventAckReceiver(this);
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
run("SensorService", PRIORITY_URGENT_DISPLAY);

直接调用threadLoop方法,

do {
    ssize_t count = device.poll(mSensorEventBuffer, numEventMax);

调用SensorDevice的poll方法读取sensor数据并且保存在mSensorEventBuffer中。具体的获取数据的过程下面再详细论述。

小结:

1,sensor服务端首先打通HAL和driver之间的通信。

2,激活各种sensor。

3,开启子线程读取sensor数据。