private void startBootstrapServices() {
...
startSensorService();
}
startsensorService是一个native函数,其具体实现在com_android_server_SystemServer.cpp的android_server_SystemServer_startSensorService函数中。
static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the sensor service
SensorService::instantiate();
}
}
SensorService::instantiate()的 instantiate函数定义在BinderService.h中,目的在于向ServiceManager注册SensorService组件。
static void instantiate() { publish(); }
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}
onFirstRef函数来自RefBase,在第一次被强指针引用时调用。
void SensorService::onFirstRef()
{
ALOGD("nuSensorService starting...");
SensorDevice& dev(SensorDevice::getInstance());
if (dev.initCheck() == NO_ERROR) {
sensor_t const* list;
ssize_t count = dev.getSensorList(&list);
if (count > 0) {
ssize_t orientationIndex = -1;
bool hasGyro = false, hasAccel = false, hasMag = false;
uint32_t virtualSensorsNeeds =
(1<<SENSOR_TYPE_GRAVITY) |
(1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
(1<<SENSOR_TYPE_ROTATION_VECTOR);
mLastEventSeen.setCapacity(count);
for (ssize_t i=0 ; i<count ; i++) {
registerSensor( new HardwareSensor(list[i]) );
switch (list[i].type) {
case SENSOR_TYPE_ACCELEROMETER:
hasAccel = true;
break;
case SENSOR_TYPE_MAGNETIC_FIELD:
hasMag = true;
break;
case SENSOR_TYPE_ORIENTATION:
orientationIndex = i;
break;
case SENSOR_TYPE_GYROSCOPE:
case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
hasGyro = true;
break;
case SENSOR_TYPE_GRAVITY:
case SENSOR_TYPE_LINEAR_ACCELERATION:
case SENSOR_TYPE_ROTATION_VECTOR:
virtualSensorsNeeds &= ~(1<<list[i].type);
break;
}
}
// it's safe to instantiate the SensorFusion object here
// (it wants to be instantiated after h/w sensors have been
// registered)
const SensorFusion& fusion(SensorFusion::getInstance());
// build the sensor list returned to users
mUserSensorList = mSensorList;
if (hasGyro && hasAccel && hasMag) {
Sensor aSensor;
// Add Android virtual sensors if they're not already
// available in the HAL
aSensor = registerVirtualSensor( new RotationVectorSensor() );
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
mUserSensorList.add(aSensor);
}
aSensor = registerVirtualSensor( new GravitySensor(list, count) );
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
mUserSensorList.add(aSensor);
}
aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
mUserSensorList.add(aSensor);
}
aSensor = registerVirtualSensor( new OrientationSensor() );
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
// if we are doing our own rotation-vector, also add
// the orientation sensor and remove the HAL provided one.
mUserSensorList.replaceAt(aSensor, orientationIndex);
}
// virtual debugging sensors are not added to mUserSensorList
registerVirtualSensor( new CorrectedGyroSensor(list, count) );
registerVirtualSensor( new GyroDriftSensor() );
}
// debugging sensor list
mUserSensorListDebug = mSensorList;
// Check if the device really supports batching by looking at the FIFO event
// counts for each sensor.
bool batchingSupported = false;
for (size_t i = 0; i < mSensorList.size(); ++i) {
if (mSensorList[i].getFifoMaxEventCount() > 0) {
batchingSupported = true;
break;
}
}
if (batchingSupported) {
// Increase socket buffer size to a max of 100 KB for batching capabilities.
mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
} else {
mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
}
// Compare the socketBufferSize value against the system limits and limit
// it to maxSystemSocketBufferSize if necessary.
FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
char line[128];
if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
line[sizeof(line) - 1] = '\0';
size_t maxSystemSocketBufferSize;
sscanf(line, "%zu", &maxSystemSocketBufferSize);
if (mSocketBufferSize > maxSystemSocketBufferSize) {
mSocketBufferSize = maxSystemSocketBufferSize;
}
}
if (fp) {
fclose(fp);
}
mWakeLockAcquired = false;
mLooper = new Looper(false);
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
mSensorEventBuffer = new sensors_event_t[minBufferSize];
mSensorEventScratch = new sensors_event_t[minBufferSize];
mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
mCurrentOperatingMode = NORMAL;
mNextSensorRegIndex = 0;
for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
mLastNSensorRegistrations.push();
}
mInitCheck = NO_ERROR;
mAckReceiver = new SensorEventAckReceiver(this);
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
run("SensorService", PRIORITY_URGENT_DISPLAY);
}
}
}
首先获得一个SensorDevice单例对象,先看看SensorDevice的默认构造函数:
SensorDevice::SensorDevice()
: mSensorDevice(0),
mSensorModule(0)
{
status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
(hw_module_t const**)&mSensorModule);
ALOGE_IF(err, "couldn't load %s module (%s)",
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
if (mSensorModule) {
err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
ALOGE_IF(err, "couldn't open device for module %s (%s)",
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
if (mSensorDevice) {
if (mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_1 ||
mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_2) {
ALOGE(">>>> WARNING <<< Upgrade sensor HAL to version 1_3");
}
sensor_t const* list;
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
mActivationCount.setCapacity(count);
Info model;
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);
}
}
}
}
谷歌为Sensor提供了统一的HAL接口,方便厂商根据该接口完成具体的硬件抽象层,接口文件在/hardware/libhardware/include/hardware/Sensors.h中。首先将
sensors_poll_device_1*类型的mSensorDevice和sensors_module_t*类型的mSensorModule成员变量设为0,这两个类型定义在Sensor.h中。sensors_module_t类型是对
hw_module_t类型的封装外加一个get_sensors_list函数。sensors_poll_device_l是对hw_device_t类型的封装外加poll(多路监听方法),activate(设备激活方法)和
setDelay(设备延迟方法)。hw_get_module是jni层获取HAL层module的接口函数,原型为hareware.c中的:int hw_get_module(const char *id, const struct
hw_module_t **module),第一个参数为硬件模块的id,第二个参数指向硬件模块对应的hw_module_t结构体地址(symbol地址)。
typedef struct sensors_poll_device_1 {
union {
/* sensors_poll_device_1 is compatible with sensors_poll_device_t,
* and can be down-cast to it
*/
struct sensors_poll_device_t v0;
struct {
struct hw_device_t common;
/* Activate/de-activate one sensor. Return 0 on success, negative
*
* sensor_handle is the handle of the sensor to change.
* enabled set to 1 to enable, or 0 to disable the sensor.
*
* Return 0 on success, negative errno code otherwise.
*/
int (*activate)(struct sensors_poll_device_t *dev,
int sensor_handle, int enabled);
/**
* Set the events's period in nanoseconds for a given sensor.
* If sampling_period_ns > max_delay it will be truncated to
* max_delay and if sampling_period_ns < min_delay it will be
* replaced by min_delay.
*/
int (*setDelay)(struct sensors_poll_device_t *dev,
int sensor_handle, int64_t sampling_period_ns);
/**
* Returns an array of sensor data.
*/
int (*poll)(struct sensors_poll_device_t *dev,
sensors_event_t* data, int count);
};
struct sensors_module_t {
struct hw_module_t common;
/**
* Enumerate all available sensors. The list is returned in "list".
* @return number of sensors in the list
*/
int (*get_sensors_list)(struct sensors_module_t* module,
struct sensor_t const** list);
/**
* Place the module in a specific mode. The following modes are defined
*
* 0 - Normal operation. Default state of the module.
* 1 - Loopback mode. Data is injected for the the supported
* sensors by the sensor service in this mode.
* @return 0 on success
* -EINVAL if requested mode is not supported
* -EPERM if operation is not allowed
*/
int (*set_operation_mode)(unsigned int mode);
};
int hw_get_module(const char *id, const struct hw_module_t **module)
{
return hw_get_module_by_class(id, NULL, module);
}
int hw_get_module_by_class(const char *class_id, const char *inst,
const struct hw_module_t **module)
{
int i = 0;
char prop[PATH_MAX] = {0};
char path[PATH_MAX] = {0};
char name[PATH_MAX] = {0};
char prop_name[PATH_MAX] = {0};
if (inst)
snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
else
strlcpy(name, class_id, PATH_MAX);//class_id拷贝到name
/*
* Here we rely on the fact that calling dlopen multiple times on
* the same .so will simply increment a refcount (and not load
* a new copy of the library).
* We also assume that dlopen() is thread-safe.
*/
/* First try a property specific to the class and possibly instance */
snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);//prop为ro.hardware.(name)
if (property_get(prop_name, prop, NULL) > 0) {//获取prop_name的属性值,保存在prop中
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {//path为/system/lib/hw/(name).(prop).so或者/vendor/lib/hw/(name).(prop).so
{
goto found;
}
}
/* Loop through the configuration variants looking for a module */
for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) {
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
goto found;
}
}
/* Nothing found, try the default */
if (hw_module_exists(path, sizeof(path), name, "default") == 0) {
goto found;
}
return -ENOENT;
found:
/* load the module, if this fails, we're doomed, and we should not try
* to load a different variant. */
return load(class_id, path, module);
}
编译好的模块文件位于out/target/product/generic/system/lib/hw(对应设备上的/system/lib/hw;/vendor/lib/hw保存设备厂商提供的HAL层模块接口文件。hw_module_exists
函数作用在于检查HAL模块接口文件是否存在。
static int load(const char *id,
const char *path,
const struct hw_module_t **pHmi)
{
int status = -EINVAL;
void *handle = NULL;
struct hw_module_t *hmi = NULL;
/*
* load the symbols resolving undefined symbols before
* dlopen returns. Since RTLD_GLOBAL is not or'd in with
* RTLD_NOW the external symbols will not be global
*/
handle = dlopen(path, RTLD_NOW);
if (handle == NULL) {
char const *err_str = dlerror();
ALOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
status = -EINVAL;
goto done;
}
/* Get the address of the struct hal_module_info. */
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
hmi = (struct hw_module_t *)dlsym(handle, sym);
if (hmi == NULL) {
ALOGE("load: couldn't find symbol %s", sym);
status = -EINVAL;
goto done;
}
/* Check that the id matches */
if (strcmp(id, hmi->id) != 0) {
ALOGE("load: id=%s != hmi->id=%s", id, hmi->id);
status = -EINVAL;
goto done;
}
hmi->dso = handle;
/* success */
status = 0;
done:
if (status != 0) {
hmi = NULL;
if (handle != NULL) {
dlclose(handle);
handle = NULL;
}
} else {
ALOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
id, path, *pHmi, handle);
}
*pHmi = hmi;
return status;
}
HAL层模块文件实际上是.so文件。dlopen以指定模式打开动态库文件,RTLD_NOW 表示立即决定,返回前解除所有未决定的符号,返回一个句柄给进程。dlsym接收句柄
和符号两个参数,返回符号的地址,并使用load函数的第三个参数指向这个符号的地址。其中HAL_MODULE_INFO_SYM_AS_STR的值为“HMI",这样便从HMI的符号确定
hw_module_t结构体的指针。根据HAL模块的编写规范,每个HAL层模块都必须包含一个名为“HMI"的符号,而且这个符号的第一个成员变量的类型必须为hw_module_t。
经过上述的分析可以知道,SensorDevice加载了sensorHAL层的动态库。然后使用sensors_open_l打开设备:
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);
}
调用hw_module_t的methods成员的open成员函数打开设备。其中hw_module_t和hw_module_method_t定义如下:
typedef struct hw_module_t {
/** tag must be initialized to HARDWARE_MODULE_TAG */
uint32_t tag;
/**
* The API version of the implemented module. The module owner is
* responsible for updating the version when a module interface has
* changed.
*
* The derived modules such as gralloc and audio own and manage this field.
* The module user must interpret the version field to decide whether or
* not to inter-operate with the supplied module implementation.
* For example, SurfaceFlinger is responsible for making sure that
* it knows how to manage different versions of the gralloc-module API,
* and AudioFlinger must know how to do the same for audio-module API.
*
* The module API version should include a major and a minor component.
* For example, version 1.0 could be represented as 0x0100. This format
* implies that versions 0x0100-0x01ff are all API-compatible.
*
* In the future, libhardware will expose a hw_get_module_version()
* (or equivalent) function that will take minimum/maximum supported
* versions as arguments and would be able to reject modules with
* versions outside of the supplied range.
*/
uint16_t module_api_version;
#define version_major module_api_version
/**
* version_major/version_minor defines are supplied here for temporary
* source code compatibility. They will be removed in the next version.
* ALL clients must convert to the new version format.
*/
/**
* The API version of the HAL module interface. This is meant to
* version the hw_module_t, hw_module_methods_t, and hw_device_t
* structures and definitions.
*
* The HAL interface owns this field. Module users/implementations
* must NOT rely on this value for version information.
*
* Presently, 0 is the only valid value.
*/
uint16_t hal_api_version;
#define version_minor hal_api_version
/** Identifier of module */
const char *id;
/** Name of this module */
const char *name;
/** Author/owner/implementor of the module */
const char *author;
/** Modules methods */
struct hw_module_methods_t* methods;
/** module's dso */
void* dso;
#ifdef __LP64__
uint64_t reserved[32-7];
#else
/** padding to 128 bytes, reserved for future use */
uint32_t reserved[32-7];
#endif
} hw_module_t;
typedef struct hw_module_methods_t {
/** Open a specific device */
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);
} hw_module_methods_t;
由于一个硬件抽象模块可能会包含多个硬件设备,因此在调用hw_module_method_t的open函数时需要指定硬件设备的id。sensors_open_l打开的设备id为
SENSORS_HARDWARE_POLL,在宏定义被定义成“poll",第三个参数device指向打开的设备对应的hw_device_t结构体指针。至此,mSensorModule保存了HAL模块对应
的hw_module_t结构体指针,mSensorDevice保存了hw_device_t指针。
在硬件抽象层模块的实现文件中(Sensors.cpp),有一个名字唯一的struct sensor_module_t变量,名字为HAL_MODULE_INFO_SYM,以Mstar的Sensors.cpp(device目
录下)为例,实现如下。其中hw_module_t成员common的methods为sensors_module_methods指针,这个sensors_module_methods为struct hw_module_methods_t。
HAL_MODULE_INFO_SYM指定了HAL层函数get_sensors_list的本地实现为sensors__get_sensors_list。sensors_module_methods指定了HAL层函数open的本地实现为
open_sensors。
struct sensors_module_t HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = SENSORS_HARDWARE_MODULE_ID,
.name = "Nanosic Sensor module",
.author = "Nanosic Tec Company",
.methods = &sensors_module_methods,
.dso = 0,
.reserved = {},
},
.get_sensors_list = sensors__get_sensors_list,
};
static struct hw_module_methods_t sensors_module_methods = {
.open = open_sensors
};
static int sensors__get_sensors_list(struct sensors_module_t* module,
struct sensor_t const** list)
{
UNUSE(module);
LOGD("call sensors__get_sensors_list, numSensors = %d", numSensors);
*list = sSensorList;
return numSensors;
}
static struct sensor_t sSensorList[LOCAL_SENSORS] = {
{ "Accelerometer Sensor",
"NGB TVOS",
1, SENSORS_ACCELERATION_HANDLE,
SENSOR_TYPE_ACCELEROMETER, RANGE_A, CONVERT_A, 0.3f, 0, 0, 0, 0, 0, 0, 0, {}},
{ "Gyroscope Sensor",
"NGB TVOS",
1, SENSORS_GYROSCOPE_HANDLE,
SENSOR_TYPE_GYROSCOPE, RANGE_GYRO, CONVERT_GYRO, 6.1f, 0, 0, 0, 0, 0, 0, 0, {}},
};
来看下open_sensors的实现。首先new了一个struct sensors_poll_context_t的变量。structsensors_poll_context_t有一个struct sensors_poll_device_t的成员device。这里把
device进行初始化,主要是将HAL层的close,activate,setDelay和poll函数的本地实现指定为poll_close,poll_activate,poll_setDelay和poll_poll,使第二个参数指向
sensors_poll_context_t成员device的hw_device_t成员common。这样,sensors_poll_context_t的第一个成员是sensors_poll_device_t。sensors_poll_device_t的第一个成员是
hw_device_t,第二个参数保存的地址是hw_device_t的地址,也就是sensors_poll_device_t和sensors_poll_context_t的首地址。
static int open_sensors(const struct hw_module_t* module, const char* id,
struct hw_device_t** device)
{
UNUSE(id);
LOGD("open_sensors()");
int status = -EINVAL;
sensors_poll_context_t *dev = new sensors_poll_context_t();
if (!dev->isValid()) {
ALOGE("Failed to open the sensors");
return status;
}
memset(&dev->device, 0, sizeof(sensors_poll_device_t));
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = SENSORS_DEVICE_API_VERSION_1_0;
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;
*device = &dev->device.common;
status = 0;
return status;
}
struct sensors_poll_context_t {
struct sensors_poll_device_t device; // must be first
sensors_poll_context_t();
~sensors_poll_context_t();
int activate(int handle, int enabled);
int setDelay(int handle, int64_t ns);
int pollEvents(sensors_event_t* data, int count);
// Will return true if the constructor completed
bool isValid() { return mInitialized; };
接着看下sensors_poll_context_t的构造函数。mSensors是一个SensorBase*指针数组,GamepadSensors,VirtualGamepadSensors均继承自SensorBase。这里就是
将sensor放入到mSensors中,初始化三个pollfd,两个监听GamepadSensors和VirtualGamepadSensors的POLLIN事件。此外还创建了管道,监听管道的读端。
SendorBase除了将一些成员变量初始化外,还使用了openInput(mDataName)方法。以GamepadSensor为例,mDataName被初始化为”RealSensor"。openInput以
mDataName作为参数,查找/dev目录下名字带有“hidraw"的设备文件并打开。
enum {
gamepad = 0,
virtualGamepad,
numSensorDrivers, // wake pipe goes here
numFds,
};
int SensorBase::openInput(const char* inputName) {
int fd = -1;
mExtConnectedDevice = DeviceMax;
if (std::string(REAL_SENSOR_NAME) == std::string(inputName)) {
const char *dirname = "/dev";
char devname[PATH_MAX];
char *filename;
DIR *dir;
struct dirent *de;
dir = opendir(dirname);
if(dir == NULL)
return -1;
strcpy(devname, dirname);
filename = devname + strlen(devname);
*filename++ = '/';
for (int i=0; i < DeviceMax; i++) {
HidrawReportDescriptor *pRptDesc = &(sensorDataConfig[i].reportDescriptor);
while((de = readdir(dir))) {
if((de->d_name[0] == '.' && (de->d_name[1] == '\0' || (de->d_name[1] == '.' && de->d_name[2] == '\0'))) ||
(std::string::npos == (std::string(de->d_name).find("hidraw"))))
continue;
strcpy(filename, de->d_name);
LOGD("devname = %s", devname);
fd = open(devname, O_RDONLY);
if (fd>=0) {
int desc_size = 0;
struct hidraw_report_descriptor rpt_desc;
memset(&rpt_desc, 0x0, sizeof(rpt_desc));
int res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);
if (res < 0) {
close(fd);
fd = -1;
LOGD("!!!Failed: ioctl(fd, HIDIOCGRDESCSIZE, &desc_size)!!!");
} else {
rpt_desc.size = desc_size;
LOGD("success: ioctl(fd, HIDIOCGRDESCSIZE, &desc_size)");
if (rpt_desc.size <= 0) {
close(fd);
fd = -1;
LOGD("!!!rpt_desc.size <= 0!!!");
break;
}
res = ioctl(fd, HIDIOCGRDESC, &rpt_desc);
if (res < 0) {
close(fd);
fd = -1;
LOGD("!!!Failed: ioctl(fd, HIDIOCGRDESC, &rpt_desc)!!!");
} else {
LOGD("rpt_desc.size = %u", rpt_desc.size);
#if 0
printf("%s :rpt_desc.size = %u, rpt_desc.value: \n", devname, rpt_desc.size);
for (unsigned int j=0; j< rpt_desc.size; j++) {
printf("%2x ", rpt_desc.value[j]);
}
printf("\n");
#endif
ExtConnectedDevice extConnectedDevice = checkConnectedDeviceByReportDescriptor(rpt_desc);
if (extConnectedDevice < DeviceMax) {
mExtConnectedDevice = extConnectedDevice;
LOGD("______________________FIND REAL SENSOR______________________");
break;
} else {
close(fd);
fd = -1;
LOGD("!!!checkConnectedDeviceByReportDescriptor(rpt_desc) return not the Device we wanted!!!");
}
}
}
} else {
LOGD("Failed: open(%s, O_RDONLY)", devname);
}
}
if (mExtConnectedDevice < DeviceMax) {
break;
}
}
closedir(dir);
}
ALOGE_IF(fd<0, "couldn't find '%s' input device", inputName);
return fd;
}
sensors_poll_context_t::sensors_poll_context_t()
{
LOGD("in sensors_poll_context_t()");
mInitialized = false;
// Must clean this up early or else the destructor will make a mess.
memset(mSensors, 0, sizeof(mSensors));
numSensors = LOCAL_SENSORS;
mSensors[gamepad] = new GamepadSensors();
mPollFds[gamepad].fd = mSensors[gamepad]->getFd();
mPollFds[gamepad].events = POLLIN;
mPollFds[gamepad].revents = 0;
mSensors[virtualGamepad] = new VirtualGamepadSensors();
mPollFds[virtualGamepad].fd = mSensors[virtualGamepad]->getFd();
mPollFds[virtualGamepad].events = POLLIN;
mPollFds[virtualGamepad].revents = 0;
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[wake].fd = wakeFds[0];
mPollFds[wake].events = POLLIN;
mPollFds[wake].revents = 0;
mInitialized = true;
LOGD("out sensors_poll_context_t()");
}
static int poll__activate(struct sensors_poll_device_t *dev,
int handle, int enabled)
{
FUNC_LOG;
sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
return ctx->activate(handle, enabled);
}
get_sensors_list会获取所有可用的sensor设备,每个sensor设备都对应一个sensor_t结构体,函数返回sensor设备的数量。之后,依次激活这些可用的sensor设备。
SensorDevice的主要工作是与HAL层进行通信,打开senser设备,加载HAL层的so文件,获得支持的传感器列表并激活。setCapacity为DefaultKeyedVector分配空间。接着
activate这些设备。前面提到mSensorDevice保存的也就是sensors_poll_device_t的地址,open_sensors将sensors_poll_device_t的activate函数设为poll_activate函数。调用
activate函数也就是调用poll_activate函数,poll_activate转而去调用sensors_poll_context_t的activate函数。
int sensors_poll_context_t::activate(int handle, int enabled)
{
LOGD("sensors_poll_context_t::activate");
if (!mInitialized) return -EINVAL;
int index = handleToDriver(handle);
if (index < 0) return index;
if(mSensors[index]->getState() == -1 && mSensors[index]->getDataName() != NULL)
{
int fd_t = mSensors[index]->getFd();
if(fd_t >= 0) {
mSensors[index]->setState(1);
} else {
mSensors[index]->setState(-1);
}
}
int err = mSensors[index]->enable(handle, enabled);
if (!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::enable函数,这是一个纯虚函数,由子类重写。以GamepadSensor为例,enable实现中调用openDevice打开设备。openDevice打开名为“RealSensor"的
文件,mDevFd保存了文件描述符。回到activate函数,最后往管道里写入一个‘W',以唤醒等待POLLIN事件的休眠线程。
int GamepadSensors::enable(int32_t handle, int enabled)
{
LOGD("GamepadSensors::enable(int32_t handle=%d, int enabled=%d)", handle, enabled);
openDevice();
return 0;
}
int SensorBase::openDevice() {
LOGD("openDevice");
if ((mDevFd < 0) && mDevName) {
mDevFd = open(mDevName, O_RDONLY);
LOGD("mDevFd = open(%s, O_RDONLY), mDevFd=%d", mDevName, mDevFd);
ALOGE_IF(mDevFd < 0, "Couldn't open %s (%s)", mDevName, strerror(errno));
}
return 0;
}
回到onFirstRef函数中,接着对获得的sensor设备列表进行注册:
for (ssize_t i=0 ; i<count ; i++) {
registerSensor( new HardwareSensor(list[i]) );
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;
}
注册虚拟传感器:
if (hasGyro && hasAccel && hasMag) {
Sensor aSensor;
// Add Android virtual sensors if they're not already
// available in the HAL
aSensor = registerVirtualSensor( new RotationVectorSensor() );// 虚拟旋转传感器
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
mUserSensorList.add(aSensor);
}
aSensor = registerVirtualSensor( new GravitySensor(list, count) );//虚拟重力传感器
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
mUserSensorList.add(aSensor);
}
aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );//虚拟加速器
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
mUserSensorList.add(aSensor);
}
aSensor = registerVirtualSensor( new OrientationSensor() );//虚拟方向传感器
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
// if we are doing our own rotation-vector, also add
// the orientation sensor and remove the HAL provided one.
mUserSensorList.replaceAt(aSensor, orientationIndex);
}
// virtual debugging sensors are not added to mUserSensorList
registerVirtualSensor( new CorrectedGyroSensor(list, count) );//真正陀螺仪
registerVirtualSensor( new GyroDriftSensor() );//虚拟陀螺测漂传感器
}
SensorService继承自Thread,末尾使用run进入SensorService::threadLoop()方法。threadLoop是父类Thread的虚函数,由子类实现。
bool SensorService::threadLoop()
{
ALOGD("nuSensorService thread starting...");
// each virtual sensor could generate an event per "real" event, that's why we need
// to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.
// in practice, this is too aggressive, but guaranteed to be enough.
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
SensorDevice& device(SensorDevice::getInstance());
const size_t vcount = mVirtualSensorList.size();
const int halVersion = device.getHalDeviceVersion();
do {
ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
if (count < 0) {
ALOGE("sensor poll failed (%s)", strerror(-count));
break;
}
// Reset sensors_event_t.flags to zero for all events in the buffer.
for (int i = 0; i < count; i++) {
mSensorEventBuffer[i].flags = 0;
}
// Make a copy of the connection vector as some connections may be removed during the
// course of this loop (especially when one-shot sensor events are present in the
// sensor_event buffer). Promote all connections to StrongPointers before the lock is
// acquired. If the destructor of the sp gets called when the lock is acquired, it may
// result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for
// cleanup. So copy all the strongPointers to a vector before the lock is acquired.
SortedVector< sp<SensorEventConnection> > activeConnections;
populateActiveConnections(&activeConnections);
Mutex::Autolock _l(mLock);
// Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
// rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
// sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
// not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
// releasing the wakelock.
bool bufferHasWakeUpEvent = false;
for (int i = 0; i < count; i++) {
if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
bufferHasWakeUpEvent = true;
break;
}
}
if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
setWakeLockAcquiredLocked(true);
}
recordLastValueLocked(mSensorEventBuffer, count);
// handle virtual sensors
if (count && vcount) {
sensors_event_t const * const event = mSensorEventBuffer;
const size_t activeVirtualSensorCount = mActiveVirtualSensors.size();
if (activeVirtualSensorCount) {
size_t k = 0;
SensorFusion& fusion(SensorFusion::getInstance());
if (fusion.isEnabled()) {
for (size_t i=0 ; i<size_t(count) ; i++) {
fusion.process(event[i]);
}
}
for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
if (count + k >= minBufferSize) {
ALOGE("buffer too small to hold all events: "
"count=%zd, k=%zu, size=%zu",
count, k, minBufferSize);
break;
}
sensors_event_t out;
SensorInterface* si = mActiveVirtualSensors.valueAt(j);
if (si->process(&out, event[i])) {
mSensorEventBuffer[count + k] = out;
k++;
}
}
}
if (k) {
// record the last synthesized values
recordLastValueLocked(&mSensorEventBuffer[count], k);
count += k;
// sort the buffer by time-stamps
sortEventBuffer(mSensorEventBuffer, count);
}
}
}
// handle backward compatibility for RotationVector sensor
if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
for (int i = 0; i < count; i++) {
if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
// All the 4 components of the quaternion should be available
// No heading accuracy. Set it to -1
mSensorEventBuffer[i].data[4] = -1;
}
}
}
// Map flush_complete_events in the buffer to SensorEventConnections which called
// flush on the hardware sensor. mapFlushEventsToConnections[i] will be the
// SensorEventConnection mapped to the corresponding flush_complete_event in
// mSensorEventBuffer[i] if such a mapping exists (NULL otherwise).
for (int i = 0; i < count; ++i) {
mMapFlushEventsToConnections[i] = NULL;
if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;
SensorRecord* rec = mActiveSensors.valueFor(sensor_handle);
if (rec != NULL) {
mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection();
rec->removeFirstPendingFlushConnection();
}
}
}
// 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);
}
}
}
if (mWakeLockAcquired && !needsWakeLock) {
setWakeLockAcquiredLocked(false);
}
} while (!Thread::exitPending());
ALOGW("Exiting SensorService::threadLoop => aborting...");
abort();
return false;
}
ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
if (!mSensorDevice) return NO_INIT;
ssize_t c;
do {
c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
buffer, count);
} while (c == -EINTR);
return c;
}
SensorDevice的poll函数会调用到sensors_poll_device_1的poll函数,前面提到open_sensors将sensors_poll_device_1的poll函数设置为poll_poll函数,poll_poll函
数调用sensors_poll_context_t::pollEvents函数。
int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
{
LOGD("---sensors_poll_context_t::pollEvents---");
int nbEvents = 0;
int n = 0;
do {
for (int i=0 ; count && i<numSensorDrivers ; i++) {
SensorBase* const sensor(mSensors[i]);
bool openFailed = false;
bool hungUp = false;
if (mSensors[i]->getFd() == -1) {
openFailed = true;
mSensors[i]->setState(-1);
LOGD("failed: open %s!!!", sensorDeviceName[i]);
} else {
if (mPollFds[i].revents & (POLLHUP | POLLERR)) {
hungUp = true;
LOGD("%s POLLHUP or POLLERR !!!", sensorDeviceName[i]);
}
}
if (hungUp) {
close(mSensors[i]->getFd());
}
if (openFailed || hungUp) {
int fd = -1;
if (i == virtualGamepad) {
fd = open(static_cast<VirtualGamepadSensors*>(mSensors[virtualGamepad])->getFifoName(), O_RDONLY | O_NONBLOCK);
} else {
fd = mSensors[i]->openInput(mSensors[i]->getDataName());
}
if (fd < 0) {
mSensors[i]->setState(-1);
LOGD("failed reopen %s !!!", sensorDeviceName[i]);
} else {
mSensors[i]->setState(1);
LOGD("success reopen %s !!!", sensorDeviceName[i]);
}
mSensors[i]->setDataFd(fd);
mPollFds[i].fd = mSensors[i]->getFd();
mPollFds[i].events = POLLIN;
mPollFds[i].revents = 0;
}
// See if we have some pending events from the last poll()
if ((mPollFds[i].revents & (POLLIN | POLLPRI)) || (sensor->hasPendingEvents())) {
LOGD("true == ((mPollFds[%d].revents & (POLLIN | POLLPRI)) || (sensor->hasPendingEvents()))", i);
int nb = sensor->readEvents(data, count);
if (nb < 0) {
LOGD("readEvents return = %d",nb);
return -errno;
}
if (nb < count) {
// no more data for this sensor
mPollFds[i].revents = 0;
}
count -= nb;
nbEvents += nb;
data += nb;
}
}
if (count) {
do {
LOGD("before poll(mPollFds, numFds(%d), nbEvents(%d) ? 0 : -1)", numFds, nbEvents);
n = poll(mPollFds, numFds, nbEvents ? 0 : -1);
LOGD("mPollFds[0].revents=%d, mPollFds[1].revents=%d", mPollFds[0].revents, mPollFds[1].revents);
LOGD("%d = poll(mPollFds, numFds, nbEvents ? 0 : -1)", n);
} while (n < 0 && errno == EINTR);
if (n < 0) {
ALOGE("poll() failed (%s)", strerror(errno));
return -errno;
}
if (mPollFds[wake].revents & (POLLIN | POLLPRI)) {
LOGD("true == (mPollFds[wake].revents & (POLLIN | POLLPRI))");
char msg;
int result = read(mPollFds[wake].fd, &msg, 1);
ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno));
ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg));
mPollFds[wake].revents = 0;
}
}
LOGD("n=%d, count=%d", n, count);
// if we have events and space, go read them
} while (n && count);
LOGD("---nbEvents=%d---", nbEvents);
return nbEvents;
}
pollEvent末尾的do-while循环会调用poll使HAL层和kernel进行通信,以监听已被初始化的mPollFds的事件。函数中还遍历了所有的mpollFds,调用readEvents进行处
理。readEvents在SensorBase的子类实现,以GamepadSensor为例,之后就是解析Gyroscope和Accelerometer的数据。
int GamepadSensors::readEvents(sensors_event_t* data, int count)
{
memset(mRawDataBuf, 0, sizeof(mRawDataBuf));
ssize_t nbytes = read(mDataFd, mRawDataBuf, sizeof(mRawDataBuf));
LOGD("%d = read(mDataFd, mRawDataBuf, sizeof(mRawDataBuf))", nbytes);
#if 1
printf("mRawDataBuf: ");
for (int i=0; i<nbytes; i++) {
printf("%02X ", mRawDataBuf[i]);
}
printf("\n");
#endif
int numEventReceived = parseRawData(mRawDataBuf, nbytes, data, count);
return numEventReceived;
}
readEvents函数从打开的InputDevice中读取数据到mRawDataBuf中,末尾调用parseRawData函数读取sensor配置参数。
int GamepadSensors::parseRawData(const char *rawDataBuf, const size_t bufSize,
struct sensors_event_t* data, int count)
{
if ((rawDataBuf == NULL) || (bufSize <= 0) || (data == NULL) || (count < 2)) {
return -EINVAL;
}
ExtConnectedDevice extConnectedDevice= getConnectedDevice();
if (extConnectedDevice >= DeviceMax) {
return -EINVAL;
}
struct timeval t;
int eventCount = 0;
SensorDataConfig config;
memset(&config, 0, sizeof(SensorDataConfig));
int ret = chooseDataConfig(config, extConnectedDevice);
if (ret < 0) {
return -EINVAL;
}//后面部分省略。。。
至此,Android Sensor的HAL层代码已基本分析完。