android-5.0 sensor工作原理—sensorservice的启动(一)

章心水
2023-12-01

sensorservice的启动:

1. systemserver.java的run函数:

 private void run() {

……

        // Initialize native services.
        System.loadLibrary("android_servers");
        nativeInit();

……

}

   Android在启动之后通过Zygote来管理和启动android server,他首先会运行SystemServer.java里面的run函数,这里主要是load android_server.so库,然后调用nativeInit()来启动sensorservice。


2. nativeInit()是本地方法,上层Java调用本地C++方法,需要通过JNI层的转化,在com_android_server_SystemServer.cpp中:

static void android_server_SystemServer_nativeInit(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();
    }
}

/*
 * JNI registration.
 */
static JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    { "nativeInit", "()V", (void*) android_server_SystemServer_nativeInit },
};

int register_android_server_SystemServer(JNIEnv* env)
{
    return jniRegisterNativeMethods(env, "com/android/server/SystemServer",
            gMethods, NELEM(gMethods));
}

首先建立nativeInit()方法对本地方法android_server_SystemServer_nativeInit()的映射,然后jniRegisterNativeMethods注册该方法,在上层调用nativeInit()方法就可以调用本地方法android_server_SystemServer_nativeInit()通过SensorService::instantiate();来实例化sensorservice,主要是向servicemanager注册sensorservice。

    static status_t publish(bool allowIsolated = false) {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(
                String16(SERVICE::getServiceName()),
                new SERVICE(), allowIsolated);
    }
  static void instantiate() { publish(); }

addservice()方法主要是完成向servicemanager注册sensorservice服务,原型如下:

 virtual status_t            addService( const String16& name,
                                            const sp<IBinder>& service,
                                            bool allowIsolated = false) = 0;

其第二个参数也就是new SERVICE()是强引用sp sensorservice,所以会调用到SensorService::onFirstRef(),这样就开始了sensorservice的一系列初始化工作。

3. SensorService::onFirstRef()

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;
            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_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) {
                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 (int 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];

            mInitCheck = NO_ERROR;
            run("SensorService", PRIORITY_URGENT_DISPLAY);
        }
    }
}
3.1 首先是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);
            }
        }
    }
}

sensorDevice的实例化主要完成以下三项工作:

3.1.1. 主要是为了从/system/lib/hw或者/vendor/lib/hw路径load一个sensors.(platform).so的库文件,如sensors.mt6753.so,第一个参数是我们所获取的hardware模块的名字,第二个参数是我们所要获得的hw_module_t。

hw_get_module(SENSORS_HARDWARE_MODULE_ID,
            (hw_module_t const**)&mSensorModule);

load()首先是通过dlopen()函数载入前面获取的path的动态链接库,如sensors.mt6753.so,然后使用dlsym()函数来获取.so文件中的符号HMI的地址,最后dlsym()函数返回hw_module_t的地址hmi,最后将hmi的值赋给参数*pHmi。load()函数的代码如下:

/**
 * Name of the hal_module_info
 */
#define HAL_MODULE_INFO_SYM         HMI

/**
 * Name of the hal_module_info as a string
 */
#define HAL_MODULE_INFO_SYM_AS_STR  "HMI"     //获取符号HMI的地址,然后dlsym()函数返回的是hw_module_t()的


static int load(const char *id,
        const char *path,
        const struct hw_module_t **pHmi)
{
    int status;
    void *handle;
    struct hw_module_t *hmi;

    /*
     * 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;
}

此处的hw_get_module()最后返回的sensors_module_t是经过封装的hw_module_t,他除了包含一个hw_module_t还包含一个获取sensorlist的API这个结构体主要是几个API接口的定义,hw_module_t结构体的定义如下:

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: "SPRD Sensor module",
				author: "Spreadtrum",
				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)
{
    *list = sSensorList;
    return numSensors;
}

3.1.2. 通过sensors_open_1(&mSensorModule->common, &mSensorDevice)函数新建并初始化系统所有的sensor。

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);
}

这里的open函数就是上一步hw_get_module()获取的sensors_module_t所定义的sensors_module_methods的open_sensors接口,open_sensors接口的代码如下:

static int open_sensors(const struct hw_module_t* module, const char* id,
                        struct hw_device_t** device)
{
        int status = -EINVAL;
        sensors_poll_context_t *dev = new sensors_poll_context_t();

        memset(&dev->device, 0, sizeof(sensors_poll_device_t));

        dev->device.common.tag = HARDWARE_DEVICE_TAG;
        dev->device.common.version  = 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;
}

函数首先是通过sensors_poll_context_t()方法新建并初始化系统所有的sensor:

sensors_poll_context_t::sensors_poll_context_t()
{
#ifndef ACC_NULL
	mSensors[acc] = new AccSensor();
	numSensors +=
	    mSensors[acc]->populateSensorList(sSensorList + numSensors);
	mPollFds[acc].fd = mSensors[acc]->getFd();
	mPollFds[acc].events = POLLIN;
	mPollFds[acc].revents = 0;
	ALOGD("AnumSensors=%d; %d", numSensors, AccSensor::numSensors);
#endif
#ifndef ORI_NULL
	mSensors[ori] = new OriSensor();
	numSensors +=
	    mSensors[ori]->populateSensorList(sSensorList + numSensors);
	mPollFds[ori].fd = mSensors[ori]->getFd();
	mPollFds[ori].events = POLLIN;
	mPollFds[ori].revents = 0;
	ALOGD("OnumSensors=%d; %d", numSensors, OriSensor::numSensors);
#endif
#ifdef SENSORHAL_PROXIMITY_STK
    mSensors[stk_als] = <span style="color:#FF0000;">new STKLightSensor();</span>
    numSensors +=
	    mSensors[stk_als]->populateSensorList(sSensorList + numSensors);
    mPollFds[stk_als].fd = mSensors[stk_als]->getFd();
    mPollFds[stk_als].events = POLLIN;
    mPollFds[stk_als].revents = 0;
	
    mSensors[stk_ps] = new STKProximitySensor();
    numSensors +=
	    mSensors[stk_ps]->populateSensorList(sSensorList + numSensors);
    mPollFds[stk_ps].fd = mSensors[stk_ps]->getFd();
    mPollFds[stk_ps].events = POLLIN;
    mPollFds[stk_ps].revents = 0;
#else
#ifndef PLS_NULL
	mSensors[pls] = new PlsSensor();
	numSensors +=
	    mSensors[pls]->populateSensorList(sSensorList + numSensors);
	mPollFds[pls].fd = mSensors[pls]->getFd();
	mPollFds[pls].events = POLLIN;
	mPollFds[pls].revents = 0;
	ALOGD("PnumSensors=%d; %d", numSensors, PlsSensor::numSensors);
#endif
#endif
	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;
}

例如在new STKLightSensor()中主要定义了数据读取环形缓冲区的大小,sensor_event_t的初始化,以及input子系统上报事件所保存的路径。STKLightSensor()代码如下:

STKLightSensor::STKLightSensor()
    : SensorBase(NULL, "lightsensor-level"),
      mEnabled(0),
      mInputReader(4),
      mHasPendingEvent(false) {
    mPendingEvent.version = sizeof(sensors_event_t);
    mPendingEvent.sensor = ID_L;
    mPendingEvent.type = SENSOR_TYPE_LIGHT;
    memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));

    if (data_fd) {
#if 1		
        strcpy(input_sysfs_path, "/sys/class/input/");
        strcat(input_sysfs_path, input_name);
        strcat(input_sysfs_path, "/device/driver/");               //此项目初始化文件节点所在文件夹目录为:/sys/class/input/input*/device/driver/
        input_sysfs_path_len = strlen(input_sysfs_path);
#else		
		strcpy(input_sysfs_path, INPUT_SYSFS_PATH_ALS);
#endif
        input_sysfs_path_len = strlen(input_sysfs_path);
		LOGD("%s: input=%s", __func__, input_name);
		LOGD("%s: input_sysfs_path = %s\n", __func__, input_sysfs_path);
    }
	
}

open_sensors第二步是对sensors_poll_device_t结构体的初始化,主要是对sensor打开,关闭,以及数据获取的API 借口的定义,这几个API接口将在后面详细描述。

3.1.3.  mSensorModule->get_sensors_list(mSensorModule, &list)这个是前面获取的sensors_module_t中定义的get_sensor_list方法。他最终获取的是HAL层初始化好的sensor的列表,并返回sensor的数量,active方法打开sensor,

mSensorDevice->activate(
                        reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
                        list[i].handle, 0);

mSensorDevice->activate()调用HAL层activate()方法,最后调用HAL层sensor厂商添加的setEnable()方法来打开对应sensor。通过open函数获取sensor在sysfs对应的文件节点,然后使用write函数往文件节点里面写1即可。

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);
}

int sensors_poll_context_t::activate(int handle, int enabled)
{
	int drv = handleToDriver(handle);                       //获取sensor的类型
	int err;

	switch (handle) {
	case ID_A:
	case ID_M:
	case ID_L:
	case ID_P:
		/* No dependencies */
		break;

	case ID_O:
		/* These sensors depend on ID_A and ID_M */
		mSensors[handleToDriver(ID_A)]->setEnable(ID_A, enabled);
		mSensors[handleToDriver(ID_M)]->setEnable(ID_M, enabled);
		break;

	default:
		return -EINVAL;
	}

	ALOGD("activate handle=%d; drv=%d", handle, drv);

	err = mSensors[drv]->setEnable(handle, enabled);                      //使用对应的sensor的setEnable方法

	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;
}

int STKLightSensor::setEnable(int32_t, int en) {
   int flags = en ? 1 : 0;
    if (flags != mEnabled) {
        int fd;
        strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); //初始化的input_sysfs_path是/sys/class/input/input*/device/driver/,此项目的文件节点是
/sys/class/input/input*/device/driver/enable,所以使用strcpy在input_sysfs_path后面添加了enable节点。
        fd = open(input_sysfs_path, O_RDWR);                        //打开对应的sysfs目录下的文件节点
		LOGE("STKLightSensor enable path %s fd %d", input_sysfs_path, fd);
        if (fd >= 0) {
            char buf[2];
            buf[1] = 0;
            if (flags) {
                buf[0] = '1';
            } else {
                buf[0] = '0';
            }
            write(fd, buf, sizeof(buf));                         //将buf的值写到sysfs的目录下面sensor对应的文件节点
            close(fd);
            mEnabled = flags;
			if(flags)
				setInitialState();                        //处理sensor开启后的第一笔数据
            return 0;
        }
        return -1;
    }
    return 0; 
}


如果打开了sensor,则会调用setInitialState()通过ioctl来从data_fd中获取数据,然后将是否有待处理数据设置为“true”,在poll后面将要讲到的poll数据时会直接先处理这个数据。这里获取的数据个人理解是在sensor开启之后的第一笔数据。

int STKLightSensor::setInitialState() {
    struct input_absinfo absinfo;
    if (!ioctl(data_fd, EVIOCGABS(ABS_MISC), &absinfo)) {
        mPendingEvent.light = (float)absinfo.value;
        mHasPendingEvent = true;
    }
	else
		ALOGE("%s:ioctl failed!", __func__);		
    return 0;
}



至此,sensorDevice的实例化就完成了。下一篇将继续讲。



 类似资料: