由於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();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<strong>extern "C" status_t system_init()</strong> { 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 <strong><span style="color: #800000;">SensorService::instantiate();</span></strong> |
frameworks\base\services\sensorservice\SensorService.cpp
2. 執行SensorService::instantiate()後, 進入SensorService::onFirstRef()
1 2 3 4 5 |
void SensorService::onFirstRef() { LOGD("nuSensorService starting..."); <strong><span style="color: #800000;"> SensorDevice& dev(SensorDevice::getInstance())</span>;</strong> |
frameworks\base\services\sensorservice\SensorDevice.cpp
3,更改呼叫SensorDevice方式
走SensorDevice& dev(SensorDevice::getInstance()); 再進入SensorDevice::SensorDevice()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
SensorDevice::SensorDevice() : mSensorDevice(0), mSensorModule(0) { status_t err = <strong><span style="color: #800000;">hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule);</span></strong> 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檔
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
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; } } <strong><span style="color: #800000;">//若以此為例, 用 SENSORS_HARDWARE_MODULE_ID 當作硬體模組ID, 則找到的 hw_get_module path=/system/lib/hw/sensors.ventana.so</span></strong> 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. */ <strong> status = load(id, path, module);</strong> } return status; } |
hardware\libhardware\hardware.c
5, 如何載入該模組
接著執行status = load(id, path, module); 就是要載入該模組
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
/** * 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; } <strong><span style="color: #800000;">//持續以SENSORS_HARDWARE_MODULE_ID 當作硬體模組ID為例, load的module=/system/lib/hw/sensors.ventana.so</span></strong> /* 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; } <strong><span style="color: #800000;">//持續以SENSORS_HARDWARE_MODULE_ID 當作硬體模組ID為例, load的symbol=HMI</span></strong> /* Check that the id matches */ if (strcmp(id, hmi->id) != 0) { LOGE("load: id=%s != hmi->id=%s", id, hmi->id); <strong><span style="color: #800000;">//持續以SENSORS_HARDWARE_MODULE_ID 當作硬體模組ID為例, load: id=sensors == hmi->id=sensors</span></strong> 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()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
/** * {@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) { } } <strong><span style="color: #800000;"> // initialize the sensor list</span></strong> <strong><span style="color: #800000;">sensors_module_init();</span></strong> 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()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
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(); } <strong><span style="color: #800000;">while (true) {</span></strong> <span style="color: #800000;"> // wait for an event</span> final int sensor = <strong><span style="color: #800000;">sensors_data_poll(sQueue, values, status, timestamp)</span>;</strong> 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.<strong><span style="color: #800000;">onSensorChangedLocked(sensorObject, values, timestamp, accuracy)</span></strong>; } } } } } //Log.d(TAG, "exiting main sensor thread"); } <strong><span style="color: #800000;"> void </span><span style="color: #800000;">onSensorChangedLocked(Sensor sensor, float[] values, long[] timestamp, int accuracy) {</span></strong> 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 這兩個比較重要
1 2 3 4 5 6 7 8 9 10 11 12 13 |
static JNINativeMethod gMethods[] = { {"nativeClassInit", "()V", (void*)nativeClassInit }, <strong><span style="color: #800000;">{"sensors_module_init","()I", (void*)sensors_module_init },</span></strong> {"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 }, <strong><span style="color: #800000;">{"sensors_data_poll", "(I[F[I[J)I", (void*)sensors_data_poll },</span></strong> }; |
frameworks\base\core\jni\android_hardware_SensorManager.cpp
3-1. 進入JNI裡面定義的sensors_module_init()
1 2 3 4 5 6 |
static jint sensors_module_init(JNIEnv *env, jclass clazz) { <strong><span style="color: #800000;"> SensorManager::getInstance();</span></strong> return 0; } |
3-2. 進入JNI裡面定義的sensors_data_poll()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
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; <strong><span style="color: #800000;"> jint accuracy = event.vector.status; </span></strong> <strong><span style="color: #800000;"> env->SetFloatArrayRegion(values, 0, 3, event.vector.v); env->SetIntArrayRegion(status, 0, 1, &accuracy); env->SetLongArrayRegion(timestamp, 0, 1, &event.timestamp);</span></strong> return event.sensor; } |
以下為HAL與Kernel之間IOCTL
HAL: vendor\3rdparty\invensense\libsensors\LightSensor.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
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, <strong>LIGHTSENSOR_IOCTL_PRIV_ENABLE</strong>, 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, <strong>LIGHTSENSOR_IOCTL_PRIV_DISABLE</strong>, 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)", <strong>LS_DEVICE_NAME</strong>, strerror(errno)); return -1; } close(fd); mEnabled = flags; return 0; } |
Kernel: kernel\drivers\misc\Al3000a.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
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 <strong>LIGHTSENSOR_IOCTL_PRIV_ENABLE</strong>: ls_enable(1); atomic_set(&ls->l_flag, 1); break; case <strong>LIGHTSENSOR_IOCTL_PRIV_DISABLE</strong>: 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; } <strong>1. 定義device node:</strong> static struct kobj_attribute light_data_attribute = <strong>__ATTR</strong>(<strong>light</strong>, 0644, data_show, data_store); static struct kobj_attribute light_lux_light_lux_attribute = <strong>__ATTR</strong>(<strong>light_lux</strong>, 0644, light_lux_show, light_lux_store); static struct kobj_attribute light_mode_light_mode_attribute = <strong>__ATTR</strong>(<strong>light_mode</strong>, 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, }; <strong>2. 其中__ATTR被定義在 kernel\include\linux\Sysfs.h</strong> #define __ATTR(_name,_mode,_show,_store) { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ } |
參考:
http://kongjian.baidu.com/%D7%D4%D3%C9%B5%C6%CB%FE/blog/item/af3454038be40efb09fa930c.html
http://www.runpc.com.tw/content/content.aspx?id=105642