Android2.3 Gsensor分析..sensor service 從android 2.2 到2.3改變很大

由於sensor service 從android 2.2 到2.3改變很大
從java service 轉為native service, 網路上找到這篇code trace, 可作研究基礎


Android2.3 Gsensor分析

以下是我的追蹤code關於開機部分:

frameworks\base\cmds\system_server\library\System_init.cpp
1: 系統開機會執行system_init()來開啟許多services
而我要追蹤的sensorService從2.2到2.3已從java service轉成native service
因此可以看到, 多了一行 SensorService::instantiate();

extern "C" status_t system_init()
{
LOGI("Entered system_init()");
sp proc(ProcessState::self());

sp sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());

sp grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);

char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}

// Start the sensor service
SensorService::instantiate();

frameworks\base\services\sensorservice\SensorService.cpp
2. 執行SensorService::instantiate()後, 進入SensorService::onFirstRef()

void SensorService::onFirstRef()
{
LOGD("nuSensorService starting...");

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

frameworks\base\services\sensorservice\SensorDevice.cpp
3,更改呼叫SensorDevice方式
走SensorDevice& dev(SensorDevice::getInstance()); 再進入SensorDevice::SensorDevice()

SensorDevice::SensorDevice()
:  mSensorDevice(0),
mSensorModule(0)
{
status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
(hw_module_t const**)&mSensorModule);

LOGE_IF(err, "couldn't load %s module (%s)",
SENSORS_HARDWARE_MODULE_ID, strerror(-err));

if (mSensorModule) {
err = sensors_open(&mSensorModule->common, &mSensorDevice);

LOGE_IF(err, "couldn't open device for module %s (%s)",
SENSORS_HARDWARE_MODULE_ID, strerror(-err));

if (mSensorDevice) {
sensor_t const* list;
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
mActivationCount.setCapacity(count);
Info model;
for (size_t i=0 ; iactivate(mSensorDevice, list[i].handle, 0);
}
}
}
}

hardware\libhardware\hardware.c
4, 如何找到正確的HAL之.so檔
hw_get_module() 會帶著hardware module的ID進入HAL層找對應的.so檔

int hw_get_module(const char *id, const struct hw_module_t **module)
{
int status;
int i;
const struct hw_module_t *hmi = NULL;
char prop[PATH_MAX];
char path[PATH_MAX];

/*
* 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.
*/

/* Loop through the configuration variants looking for a module */
for (i=0 ; i         if (i < HAL_VARIANT_KEYS_COUNT) {
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
snprintf(path, sizeof(path), "%s/%s.%s.so",
HAL_LIBRARY_PATH1, id, prop);
if (access(path, R_OK) == 0) break;

snprintf(path, sizeof(path), "%s/%s.%s.so",
HAL_LIBRARY_PATH2, id, prop);
if (access(path, R_OK) == 0) break;
} else {
snprintf(path, sizeof(path), "%s/%s.default.so",
HAL_LIBRARY_PATH1, id);
if (access(path, R_OK) == 0) break;
}
}

//若以此為例, 用 SENSORS_HARDWARE_MODULE_ID 當作硬體模組ID, 則找到的 hw_get_module path=/system/lib/hw/sensors.ventana.so

status = -ENOENT;
if (i < HAL_VARIANT_KEYS_COUNT+1) {
/* load the module, if this fails, we're doomed, and we should not try
* to load a different variant. */
 status = load(id, path, module);
}

return status;
}

hardware\libhardware\hardware.c
5, 如何載入該模組
接著執行status = load(id, path, module); 就是要載入該模組

/**
* Load the file defined by the variant and if successful
* return the dlopen handle and the hmi.
* @return 0 = success, !0 = failure.
*/
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();
LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
status = -EINVAL;
goto done;
}

//持續以SENSORS_HARDWARE_MODULE_ID 當作硬體模組ID為例, load的module=/system/lib/hw/sensors.ventana.so

/* 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) {
LOGE("load: couldn't find symbol %s", sym);
status = -EINVAL;
goto done;
}
//持續以SENSORS_HARDWARE_MODULE_ID 當作硬體模組ID為例, load的symbol=HMI

/* Check that the id matches */
if (strcmp(id, hmi->id) != 0) {
LOGE("load: id=%s != hmi->id=%s", id, hmi->id);
//持續以SENSORS_HARDWARE_MODULE_ID 當作硬體模組ID為例, load: id=sensors == hmi->id=sensors
status = -EINVAL;
goto done;
}

hmi->dso = handle;

/* success */
status = 0;

done:
if (status != 0) {
hmi = NULL;
if (handle != NULL) {
dlclose(handle);
handle = NULL;
}
} else {
LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
id, path, *pHmi, handle);
}

*pHmi = hmi;

return status;
}

以下是我的追蹤code關於開啟SensorsTest.apk部分:

frameworks\base\core\java\android\hardware\SensorManager.java
1-1, 上層Aplication會往下層要資料, 首先看一下上層JAVA部分sensors_module_init()

/**
* {@hide}
*/
public SensorManager(Looper mainLooper) {
mMainLooper = mainLooper;

synchronized(sListeners) {
if (!sSensorModuleInitialized) {
sSensorModuleInitialized = true;

nativeClassInit();

sWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
if (sWindowManager != null) {
// if it's null we're running in the system process
// which won't get the rotated values
try {
sRotation = sWindowManager.watchRotation(
new IRotationWatcher.Stub() {
public void onRotationChanged(int rotation) {
SensorManager.this.onRotationChanged(rotation);
}
}
);
} catch (RemoteException e) {
}
}

 // initialize the sensor list
sensors_module_init();
final ArrayList fullList = sFullSensorsList;
int i = 0;
do {
Sensor sensor = new Sensor();
i = sensors_module_get_next_sensor(sensor, i);

if (i>=0) {
//Log.d(TAG, "found sensor: " + sensor.getName() +
//        ", handle=" + sensor.getHandle());
sensor.setLegacyType(getLegacySensorType(sensor.getType()));
fullList.add(sensor);
sHandleToSensor.append(sensor.getHandle(), sensor);
}
} while (i>0);

sPool = new SensorEventPool( sFullSensorsList.size()*2 );
sSensorThread = new SensorThread();
}
}
}

frameworks\base\core\java\android\hardware\SensorManager.java
1-2, 上層Aplication會往下層要資料, 首先看一下上層JAVA部分sensors_data_poll()

private class SensorThreadRunnable implements Runnable {
SensorThreadRunnable() {
}

private boolean open() {
// NOTE: this cannot synchronize on sListeners, since
// it's held in the main thread at least until we
// return from here.
sQueue = sensors_create_queue();
return true;
}

public void run() {
//Log.d(TAG, "entering main sensor thread");
final float[] values = new float[3];
final int[] status = new int[1];
final long timestamp[] = new long[1];
Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);

if (!open()) {
return;
}

synchronized (this) {
// we've open the driver, we're ready to open the sensors
mSensorsReady = true;
this.notify();
}

while (true) {
 // wait for an event
final int sensor = sensors_data_poll(sQueue, values, status, timestamp);

int accuracy = status[0];
synchronized (sListeners) {
if (sensor == -1 || sListeners.isEmpty()) {
// we lost the connection to the event stream. this happens
// when the last listener is removed or if there is an error
if (sensor == -1 && !sListeners.isEmpty()) {
// log a warning in case of abnormal termination
Log.e(TAG, "_sensors_data_poll() failed, we bail out: sensors=" + sensor);
}
// we have no more listeners or polling failed, terminate the thread
sensors_destroy_queue(sQueue);
sQueue = 0;
mThread = null;
break;
}
final Sensor sensorObject = sHandleToSensor.get(sensor);
if (sensorObject != null) {
// report the sensor event to all listeners that
// care about it.
final int size = sListeners.size();
for (int i=0 ; i                                 ListenerDelegate listener = sListeners.get(i);
if (listener.hasSensor(sensorObject)) {
// this is asynchronous (okay to call
// with sListeners lock held).
listener.onSensorChangedLocked(sensorObject, values, timestamp, accuracy);
}
}
}
}
}
//Log.d(TAG, "exiting main sensor thread");
}

 void onSensorChangedLocked(Sensor sensor, float[] values, long[] timestamp, int accuracy) {
SensorEvent t = sPool.getFromPool();
final float[] v = t.values;
v[0] = values[0];
v[1] = values[1];
v[2] = values[2];
t.timestamp = timestamp[0];
t.accuracy = accuracy;
t.sensor = sensor;
Message msg = Message.obtain();
msg.what = 0;
msg.obj = t;
mHandler.sendMessage(msg);
}

frameworks\base\core\jni\android_hardware_SensorManager.cpp
2, 執行sensors_module_init(), 進入JNI 的部分, 先看一下對應表(native<->java)
注意一下: sensors_module_init, sensors_data_poll 這兩個比較重要

static JNINativeMethod gMethods[] = {
{"nativeClassInit", "()V",              (void*)nativeClassInit },
{"sensors_module_init","()I",           (void*)sensors_module_init },
{"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",
(void*)sensors_module_get_next_sensor },

{"sensors_create_queue",  "()I",        (void*)sensors_create_queue },
{"sensors_destroy_queue", "(I)V",       (void*)sensors_destroy_queue },
{"sensors_enable_sensor", "(ILjava/lang/String;II)Z",
(void*)sensors_enable_sensor },

{"sensors_data_poll",  "(I[F[I[J)I",     (void*)sensors_data_poll },
};

frameworks\base\core\jni\android_hardware_SensorManager.cpp
3-1. 進入JNI裡面定義的sensors_module_init()

static jint
sensors_module_init(JNIEnv *env, jclass clazz)
{
 SensorManager::getInstance();
return 0;
}

3-2. 進入JNI裡面定義的sensors_data_poll()

static jint
sensors_data_poll(JNIEnv *env, jclass clazz, jint nativeQueue,
jfloatArray values, jintArray status, jlongArray timestamp)
{
sp queue(reinterpret_cast(nativeQueue));
if (queue == 0) return -1;

status_t res;
ASensorEvent event;

res = queue->read(&event, 1);
if (res == -EAGAIN) {
res = queue->waitForEvent();
if (res != NO_ERROR)
return -1;
res = queue->read(&event, 1);
}
if (res < 0)         return -1;

 jint accuracy = event.vector.status; 

 env->SetFloatArrayRegion(values, 0, 3, event.vector.v);
env->SetIntArrayRegion(status, 0, 1, &accuracy);
env->SetLongArrayRegion(timestamp, 0, 1, &event.timestamp);

return event.sensor;
}

以下為HAL與Kernel之間IOCTL

HAL: vendor\3rdparty\invensense\libsensors\LightSensor.cpp

int LightSensor::enable(int32_t handle, int en)
{
	int flags = en ? 1 : 0;
	mEventsSinceEnable = 0;
	mPreviousLight = -1;
	int fd, rc;
	fd = open(input_sysfs_path, O_RDONLY);

	if (fd >= 0) {
		if (flags) {
			rc = ioctl(fd, LIGHTSENSOR_IOCTL_PRIV_ENABLE, LIGHTSENSOR_IOCTL_PRIV_ENABLE);
			if (rc < 0)
				LOGE("LIGHTSENSOR_IOCTL_PRIV_ENABLE error (%s)", strerror(errno));
			else
				LOGD("[%s]: going to enabled\n", input_sysfs_path);
		} else {
			rc = ioctl(fd, LIGHTSENSOR_IOCTL_PRIV_DISABLE, LIGHTSENSOR_IOCTL_PRIV_DISABLE);
			if (rc < 0)
				LOGE("LIGHTSENSOR_IOCTL_PRIV_DIASBLE error (%s)", strerror(errno));
			else
				LOGD("[%s]: going to disabled\n", input_sysfs_path);
		}
	} else {
		LOGE("Couldn't open %s (%s)", LS_DEVICE_NAME, strerror(errno));
		return -1;
	}
	close(fd);
	mEnabled = flags;
	return 0;
}

Kernel: kernel\drivers\misc\Al3000a.c

static int
light_misc_ioctl(struct inode *inode, struct file *file,
		unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int flag = 0;

	switch (cmd) {
		case LIGHTSENSOR_IOCTL_PRIV_ENABLE:
			ls_enable(1);
			atomic_set(&ls->l_flag, 1);
		break;
		case LIGHTSENSOR_IOCTL_PRIV_DISABLE:
			ls_enable(0);
			atomic_set(&ls->l_flag, 0);
		break;
		default:
			pr_err("%s: miss ioctl cmd:0x%X\n", __func__, cmd);
			return -ENOTTY;
		break;
	}

	return 0;
}


1. 定義device node:

static struct kobj_attribute light_data_attribute =
	__ATTR(light, 0644, data_show, data_store);

static struct kobj_attribute light_lux_light_lux_attribute =
	__ATTR(light_lux, 0644, light_lux_show, light_lux_store);

static struct kobj_attribute light_mode_light_mode_attribute =
	__ATTR(light_mode, 0644, light_mode_show, light_mode_store);

static struct attribute *attrs[] = {
	&light_data_attribute.attr,
	&light_lux_light_lux_attribute.attr,
	&light_mode_light_mode_attribute.attr,
	NULL,
};

static struct attribute_group attr_group = {
	.attrs = attrs,
};

2. 其中__ATTR被定義在 kernel\include\linux\Sysfs.h
#define __ATTR(_name,_mode,_show,_store) { \
	.attr = {.name = __stringify(_name), .mode = _mode },	\
	.show	= _show,					\
	.store	= _store,					\
}

2 thoughts on “Android2.3 Gsensor分析..sensor service 從android 2.2 到2.3改變很大

發表迴響