Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3037401
  • 博文数量: 674
  • 博客积分: 17881
  • 博客等级: 上将
  • 技术积分: 4849
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 10:15
文章分类

全部博文(674)

文章存档

2013年(34)

2012年(146)

2011年(197)

2010年(297)

分类: LINUX

2011-05-20 17:48:07

虽然这篇文章写得很差,因为赶时间,所以就匆匆忙忙地写出来自己作一个笔记。但是我想对大家应该有一点帮助。
1、有关sensor在Java应用程序的编程(以注册多个传感器为例,这程序是我临时弄出来的,可能有错)
package com.sensors.acc;
 
import android.app.Activity;
import android.os.Bundle;
 
import android.util.Log;
import android.widget.TextView;
import android.hardware.SensorManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
 
public class acc extends Activity {
    float x, y, z;
    SensorManager sensormanager = null;
    Sensor accSensor = null;
    Sensor lightSensor = null;
    Sensor proximitySensor = null;
    TextView accTextView = null;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    sensormanager = (SensorManager)getSystemService(SENSOR_SERVICE);
    accSensor = sensormanager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    lightSensor = sensormanager.getDefaultSensor(Sensor.TYPE_LIGHT);
    proximitySensor = sensormanager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    accTextView = (TextView)findViewById(R.id.textview_name);
    }
   
    SensorEventListener lsn = new SensorEventListener() {  
        public void onSensorChanged(SensorEvent e) {
        if (e.sensor == accSensor) {
             Log.d("sensor", "found acc sensor");
                x = e.values[SensorManager.DATA_X];  
                y = e.values[SensorManager.DATA_Y];  
                z = e.values[SensorManager.DATA_Z];
                accTextView.setText("x = " + x + ", \ny = " + y + ", \nz = " + z);
        }
        else if (e.sensor == lightSensor) {
             Log.d("sensor", "found light sensor");
                accTextView.setText("data is " + e.values[0]);
        }
        else if (e.sensor == proximitySensor) {
             Log.d("sensor", "found proximity sensor");
                accTextView.setText("distance is " + e.values[0]);
        }
  //          Log.d("sensor", "found acc sensor");
 
 //           Log.d("sensor", "x = " + x + ", y = " + y + ", z = " + z);
 //           accTextView.setText("x = " + x + ", \ny = " + y + ", \nz = " + z);
        }  
 
        public void onAccuracyChanged(Sensor s, int accuracy) {  
        }  
    };    
    @Override   
    protected void onResume() {       
    super.onResume();      // register this class as a listener for the orientation and accelerometer sensors       
    sensormanager.registerListener(lsn, accSensor, SensorManager.SENSOR_DELAY_NORMAL);
    sensormanager.registerListener(lsn, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
    sensormanager.registerListener(lsn, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
 //     sensormanager.unregisterListener(lsn);
    }       
    @Override   
    protected void onStop() {        // unregister listener       
    sensormanager.unregisterListener(lsn, accSensor);
    sensormanager.unregisterListener(lsn, lightSensor);
sensormanager.unregisterListener(lsn, proximitySensor);
    super.onStop();   
    }  
}
 
在onCreate()函数中,调用getSystemService(SENSOR_SERVICE)初始化一个SensorManager实例,为什么要用getSystemService函数,而不直接用new SensorManager呢?我们看此函数的实现,在ApplicationContext.java中,
if (SENSOR_SERVICE.equals(name)) {
            return getSensorManager();
然后getSensorManager()的实现
 

    private SensorManager getSensorManager() {
        synchronized (mSync) {
            if (mSensorManager == null) {
                mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
            }
        }
        return mSensorManager;
}
看到没有?初始化SensorManager的时候需要mMainThread.getHandler().getLooper()这个参数,之个应该是用来传递消息用的,在SensorManager类的构造函数中会把此参数传给类成员mMainLooper。如果用new SensorManager()就需要另外获取mainLooper参数传递进去。
 
2、在android中跟sensor有关的一些文件有SensorManager.java,位于frameworks\base\core\java\android\hardware目录下,SensorService.java,位于frameworks\base\services\java\com\android\server目录下,android_hardware_SensorManager.cpp,位于frameworks\base\core\jni\目录下,与SensorManager.java相对应,com_android_server_SensorService.cpp,在frameworks\base\services\jni\目录下,与SensorService.java相对应。还有SystemServer.java文件,Hardware\Libhardware\Include\Hardware目录下的Sensor.h头文件。另外我们需要根据Sensor.h实现自己的一个源文件,一般取名为sensors_xxx.c或者sensors_xxx.cpp。
 
3、SensorManager类分析
有几个函数比较重要,必须清晰理解它们的实现,才能了解整个传感器系统的实现。从而更好地去实现硬件抽象层的实现。几个比较重要的函数有构造函数SensorManager(), registerListener()和unregisterListener(),其中registerListener()和unregisterListener()有多个,标志为  @Deprecated的是过时的,就不要看了。
(1)构造函数SensorManager(Looper mainLooper)
这个函数首先获取得传感器系统服务,并赋给类成员mSensorService,
       mSensorService = ISensorService.Stub.asInterface(
                ServiceManager.getService(Context.SENSOR_SERVICE));
这里我要说一句,就是关于这个传感器系统服务,很多书上都说用getSystemService()是获得传感器的系统服务,而它返回的是SensorManager类型,所以以为整个系统都是使用同一个SensorManager类的实例,以为我们在任何地方使用的SensorManager实例都是同一个,它们的公共成员是共享的。但是经过这两天的分析,这种说法是错误的。其实每次调用getSystemService()函数时都初始化一个新的SensorManager实例,而这个SensorManager实例会在构造函数里通过取得传感器系统服务SensorService来实现对下层传感器的一些控制。而这个SensorService才是系统的传感器服务,说服务,不如说它只是SensorService类的一个实例罢了。它只在系统初始化时初始化一次。Android中的系统服务机制应该跟传感器的都差不多一个样,都是由不同的Manager调用下层相同的Service。你可以列举其它的Manager。那它是什么时候初始化呢?它是系统初始化在SystemServer进程里创建的,SystemServer是一个管理很多系统服务的进程,我们转到SystemServer.的main函数里,可以看到一直到调用int2()函数,它会创建一个ServerThread,最终调用AdbSettingsObserver类的run()函数,在run()函数里有这么有一句
            // Sensor Service is needed by Window Manager, so this goes first
            Log.i(TAG, "Sensor Service");
            ServiceManager.addService(Context.SENSOR_SERVICE, new SensorService(context));
这里就创建SensorService实例了。在创建这个实例时会在SensorService构造函数中调用jni函数    public SensorService(Context context) {
        if (localLOGV) Log.d(TAG, "SensorService startup");
        _sensors_control_init();
    }
我们看_sensors_control_init();对应的为
static jint
android_init(JNIEnv *env, jclass clazz)
{
    sensors_module_t* module;
    if (hw_get_module(SENSORS_HARDWARE_MODULE_ID, (const hw_module_t**)&module) == 0) {
        if (sensors_control_open(&module->common, &sSensorDevice) == 0) {
            const struct sensor_t* list;
            int count = module->get_sensors_list(module, &list);
            return count;
        }
    }
    return 0;
}
它主要调用了sensor.h中的sensors_control_open()
static inline int sensors_control_open(const struct hw_module_t* module,
        struct sensors_control_device_t** device) {
    return module->methods->open(module,
            SENSORS_HARDWARE_CONTROL, (struct hw_device_t**)device);
}
之后在系统任何地方使用的都是这个SensorService实例。最后run()函数调用Looper.loop();就进行消息循环等待了,这就是SystemServer进程的消息服务了。这才真正叫做系统服务嘛。
 
我们继续看SensorManager类的构造函数,取得SensorService后,
               nativeClassInit();
这是一个jni函数,SensorManager类调用的jni函数都在com_android_server_SensorService.cpp里,我们看这函数
static void
nativeClassInit (JNIEnv *_env, jclass _this)
{
    jclass sensorClass = _env->FindClass("android/hardware/Sensor");
    SensorOffsets& sensorOffsets = gSensorOffsets;
    sensorOffsets.name        = _env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;");
    sensorOffsets.vendor      = _env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");
    sensorOffsets.version     = _env->GetFieldID(sensorClass, "mVersion",   "I");
    sensorOffsets.handle      = _env->GetFieldID(sensorClass, "mHandle",    "I");
    sensorOffsets.type        = _env->GetFieldID(sensorClass, "mType",      "I");
    sensorOffsets.range       = _env->GetFieldID(sensorClass, "mMaxRange",  "F");
    sensorOffsets.resolution  = _env->GetFieldID(sensorClass, "mResolution","F");
    sensorOffsets.power       = _env->GetFieldID(sensorClass, "mPower",     "F");
}
这个函数只是获取和设置一些信息吧,我们不关心。接着
                sensors_module_init();
我们看这函数
static jint
sensors_module_init(JNIEnv *env, jclass clazz)
{
    int err = 0;
    sensors_module_t const* module;
    err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (const hw_module_t **)&module);
    if (err == 0)
        sSensorModule = (sensors_module_t*)module;
    return err;
}
它获取了sensor的模块信息,并把它赋给sSensorModule全局变量,之后传的modules参数都为这个。
接着在构造函数里
            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);
这里主要是通过jni函数sensors_module_get_next_sensor(sensor, i);获取传感器列表,并把它加入自己的fullList列表中。我们看sensors_module_get_next_sensor()函数
static jint
sensors_module_get_next_sensor(JNIEnv *env, jobject clazz, jobject sensor, jint next)
{
    if (sSensorModule == NULL)
        return 0;
 
    SensorOffsets& sensorOffsets = gSensorOffsets;
    const struct sensor_t* list;
    int count = sSensorModule->get_sensors_list(sSensorModule, &list);
    if (next >= count)
        return -1;
   
    list += next;
 
    jstring name = env->NewStringUTF(list->name);
    jstring vendor = env->NewStringUTF(list->vendor);
    env->SetObjectField(sensor, sensorOffsets.name,      name);
    env->SetObjectField(sensor, sensorOffsets.vendor,    vendor);
    env->SetIntField(sensor, sensorOffsets.version,      list->version);
    env->SetIntField(sensor, sensorOffsets.handle,       list->handle);
    env->SetIntField(sensor, sensorOffsets.type,         list->type);
    env->SetFloatField(sensor, sensorOffsets.range,      list->maxRange);
    env->SetFloatField(sensor, sensorOffsets.resolution, list->resolution);
    env->SetFloatField(sensor, sensorOffsets.power,      list->power);
   
    next++;
    return next
}
它主要是调用HAL层的get_sensors_list()函数取得传感器列表信息。
接着在sensorManger构造函数最后
                sSensorThread = new SensorThread();
创建一个SensorThread()线程。但并未运行,但在SensorThread类的构造函数里会执行jni函数            sensors_data_init();
我们看此函数static jint
sensors_data_init(JNIEnv *env, jclass clazz)
{
    if (sSensorModule == NULL)
        return -1;
    int err = sensors_data_open(&sSensorModule->common, &sSensorDevice);
    return err;
}
它调用了HAL层的sensors_data_open函数,而这个函数位于sensor.h中,它调用的是
static inline int sensors_data_open(const struct hw_module_t* module,
        struct sensors_data_device_t** device) {
    return module->methods->open(module,
            SENSORS_HARDWARE_DATA, (struct hw_device_t**)device);
}
Modules->methods->open函数。而在SensorThread类的析构函数finalize()里会调用
            sensors_data_uninit();
static jint
sensors_data_uninit(JNIEnv *env, jclass clazz)
{
    int err = 0;
    if (sSensorDevice) {
        err = sensors_data_close(sSensorDevice);
        if (err == 0)
            sSensorDevice = 0;
    }
    return err;
}
在sensor.h里
static inline int sensors_data_close(struct sensors_data_device_t* device) {
    return device->common.close(&device->common);
}
那什么时候sSensorThread线程会运行呢?我们在下面看registerListener()函数。
 
(2)    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) {
        return registerListener(listener, sensor, rate, null);
}
它调用的是    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate,
            Handler handler)
在这函数中,先验证rate,然后检测注册的listener在不在本类的sListeners列表中。
                for (ListenerDelegate i : sListeners) {
                    if (i.getListener() == listener) {
                        l = i;
                        break;
                    }
                }
如果不在就申请一个listener,并把它加入全局列表sListener中,并调用mSensorService的enableSensor()函数使能传感器,这个enableSensor()函数最终会调用HAL层的active函数和set_delay()函数,使用后然后判断sListener列表是否为空,当然,第一次为空时加入一个新的listener就不为空了,此时就执行sSensorThread的startLocked运行sSensorThread线程了
          l = new ListenerDelegate(listener, sensor, handler);
                    result = mSensorService.enableSensor(l, name, handle, delay);
                    if (result) {
                        sListeners.add(l);
                        sListeners.notify();
                    }
                    if (!sListeners.isEmpty()) {
                        sSensorThread.startLocked(mSensorService);
                    }
另一方面,如果注册的listener在sListeners列表中,则先调用mSensorService的enableSensor()函数使能传感器,然后把注册的传感器加入到已存在的listener中。
                 result = mSensorService.enableSensor(l, name, handle, delay);
                    if (result) {
                        l.addSensor(sensor);
                    }
接下来我们看看startLocked函数,它在SensorThread中,
        void startLocked(ISensorService service) {
            try {
                if (mThread == null) {
                    Bundle dataChannel = service.getDataChannel();
                    mThread = new Thread(new SensorThreadRunnable(dataChannel),
                            SensorThread.class.getName());
                    mThread.start();
                }
            } catch (RemoteException e) {
                Log.e(TAG, "RemoteException in startLocked: ", e);
            }
        }
第一次mThread为null,然后它调用了service.getDataChannel()函数,此函数在SensorService类中,主要调用了jni函数_sensors_control_open(),
    public Bundle getDataChannel() throws RemoteException {
        // synchronize so we do not require sensor HAL to be thread-safe.
        synchronized(mListeners) {
            return _sensors_control_open();
        }
}
SensorService类中调用的jni函数主要都在com_android_server_SensorService.cpp文件 中,我们看一下这个函数
static jobject
android_open(JNIEnv *env, jclass clazz)
{
    native_handle_t* handle = sSensorDevice->open_data_source(sSensorDevice);
    if (!handle) {
        return NULL;
    }
 
    // new Bundle()
    jobject bundle = env->NewObject(
            gBundleOffsets.mClass,
            gBundleOffsets.mConstructor);
 
    if (handle->numFds > 0) {
        jobjectArray fdArray = env->NewObjectArray(handle->numFds,
                gParcelFileDescriptorOffsets.mClass, NULL);
        for (int i = 0; i < handle->numFds; i++) {
            // new FileDescriptor()
            jobject fd = env->NewObject(gFileDescriptorOffsets.mClass,
                    gFileDescriptorOffsets.mConstructor);
            env->SetIntField(fd, gFileDescriptorOffsets.mDescriptor, handle->data[i]);
            // new ParcelFileDescriptor()
            jobject pfd = env->NewObject(gParcelFileDescriptorOffsets.mClass,
                    gParcelFileDescriptorOffsets.mConstructor, fd);
            env->SetObjectArrayElement(fdArray, i, pfd);
        }
        // bundle.putParcelableArray("fds", fdArray);
        env->CallVoidMethod(bundle, gBundleOffsets.mPutParcelableArray,
                env->NewStringUTF("fds"), fdArray);
    }
 
    if (handle->numInts > 0) {
        jintArray intArray = env->NewIntArray(handle->numInts);
        env->SetIntArrayRegion(intArray, 0, handle->numInts, &handle->data[handle->numInts]);
        // bundle.putIntArray("ints", intArray);
        env->CallVoidMethod(bundle, gBundleOffsets.mPutIntArray,
                env->NewStringUTF("ints"), intArray);
    }
 
    // delete the file handle, but don't close any file descriptors
    native_handle_delete(handle);
    return bundle;
}
它主要调用了HAL层的open_data_source()函数。取得一些文件描述符等信息。
接下来SensorThread创建一个线程,调用start()就进入SensorThreadRunnable类的run()函数了,所以我们接着去看run()函数,它首先调用open()函数
                if (!open()) {
                    return;
                }
在open()函数中调用了  jni函数sensors_data_open(fds, ints);
static jint
sensors_data_open(JNIEnv *env, jclass clazz, jobjectArray fdArray, jintArray intArray)
{
    jclass FileDescriptor = env->FindClass("java/io/FileDescriptor");
    jfieldID fieldOffset = env->GetFieldID(FileDescriptor, "descriptor", "I");
    int numFds = (fdArray ? env->GetArrayLength(fdArray) : 0);
    int numInts = (intArray ? env->GetArrayLength(intArray) : 0);
    native_handle_t* handle = native_handle_create(numFds, numInts);
    int offset = 0;
 
    for (int i = 0; i < numFds; i++) {
        jobject fdo = env->GetObjectArrayElement(fdArray, i);
        if (fdo) {
            handle->data[offset++] = env->GetIntField(fdo, fieldOffset);
        } else {
            handle->data[offset++] = -1;
        }
    }
    if (numInts > 0) {
        jint* ints = env->GetIntArrayElements(intArray, 0);
        for (int i = 0; i < numInts; i++) {
            handle->data[offset++] = ints[i];
        }
        env->ReleaseIntArrayElements(intArray, ints, 0);
    }
 
    // doesn't take ownership of the native handle
    return sSensorDevice->data_open(sSensorDevice, handle);
}
这函数最终调用了HAL层的data_open(),之后run()函数就进入一个while循环了。
         while (true) {
                    // wait for an event
                    final int sensor = sensors_data_poll(values, status, timestamp);
 
                    int accuracy = status[0];
                    synchronized (sListeners) {
                        if (sensor == -1 || sListeners.isEmpty()) {
                            if (sensor == -1) {
                                // we lost the connection to the event stream. this happens
                                // when the last listener is removed.
                                Log.d(TAG, "_sensors_data_poll() failed, we bail out.");
                            }
 
                            // we have no more listeners or polling failed, terminate the thread
                            sensors_data_close();
                            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);
                                }
                            }
                        }
                    }
它调用了jni函数sensors_data_poll()一直读数据。
static jint
sensors_data_poll(JNIEnv *env, jclass clazz,
        jfloatArray values, jintArray status, jlongArray timestamp)
{
    sensors_data_t data;
    int res = sSensorDevice->poll(sSensorDevice, &data);
    if (res >= 0) {
        jint accuracy = data.vector.status;
        env->SetFloatArrayRegion(values, 0, 3, data.vector.v);
        env->SetIntArrayRegion(status, 0, 1, &accuracy);
        env->SetLongArrayRegion(timestamp, 0, 1, &data.time);
    }
 
    return res;
}
把传感器得到的值都放在value数组中,根据返回的传感器标志sensor,把它分派给在sListener列表中所有的listener,如果listener中有监听这个sensor,就把它分派给这个listener,此时就会引起onSensorChange()了。
 
好了,获取传感器数据主要是这样一个途径。最后我们去分析一下unregisterListener()函数。
   private void unregisterListener(Object listener) {
        if (listener == null) {
            return;
        }
        try {
            synchronized (sListeners) {
                final int size = sListeners.size();
                for (int i=0 ; i
                    ListenerDelegate l = sListeners.get(i);
                    if (l.getListener() == listener) {
                        // disable all sensors for this listener
                        for (Sensor sensor : l.getSensors()) {
                            String name = sensor.getName();
                            int handle = sensor.getHandle();
                            mSensorService.enableSensor(l, name, handle, SENSOR_DISABLE);
                        }
                        sListeners.remove(i);
                        break;
                    }
                }
            }
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException in unregisterListener: ", e);
        }
}
不用想这个函数会做一些与registerListener相反的事情,至少差不多。它先在sListeners列表中找到这个listener,然后先调用enableSensor()函数禁止这个传感器。我们跟踪一下这函数,在SensorService类中。
      synchronized(mListeners) {
            if (enable!=SENSOR_DISABLE && !_sensors_control_activate(sensor, true)) {
                Log.w(TAG, "could not enable sensor " + sensor);
                return false;
            }
                   
            Listener l = null;
            int minDelay = enable;
            for (Listener listener : mListeners) {
                if (binder == listener.mToken) {
                    l = listener;
                }
                if (minDelay > listener.mDelay)
                    minDelay = listener.mDelay;
            }
           
            if (l == null && enable!=SENSOR_DISABLE) {
                l = new Listener(binder);
                binder.linkToDeath(l, 0);
                mListeners.add(l);
                mListeners.notify();
            }
           
            if (l == null) {
                // by construction, this means we're disabling a listener we
                // don't know about...
                Log.w(TAG, "listener with binder " + binder +
                        ", doesn't exist (sensor=" + name + ", id=" + sensor + ")");
                return false;
            }
           
            if (minDelay >= 0) {
                _sensors_control_set_delay(minDelay);
            }
           
            if (enable != SENSOR_DISABLE) {
                l.addSensor(sensor, enable);
            } else {
                l.removeSensor(sensor);
                deactivateIfUnusedLocked(sensor);
                if (l.mSensors == 0) {
                    mListeners.remove(l);
                    binder.unlinkToDeath(l, 0);
                    mListeners.notify();
                }
            }
           
            if (mListeners.size() == 0) {
                _sensors_control_wake();
                _sensors_control_close();
            }
        }       
        return true;
你们看到它的实现了吧。如果enable是true的话,就调用_sensors_control_activate(),如果是false的话,就调用deactivateIfUnusedLocked(),它们最终都会调用 HAL层的active()函数。最后,如果是禁止传感器的话,如果mListeners为空了,它就会调用
_sensors_control_wake();
                _sensors_control_close();
这两个jni函数,最终会调用HAL层的wake()和close_data_source()函数。当调用wake()函数时,会使SensorManager类线程的run()函数中的sensor_data_poll()函数立即返回,此时在run()函数中调用sensors_data_close();最终会调用HAL层的data_close()函数。至此,一个传感器从初始到结束的流程就分析完了。
       所以在java使用一个传感器在HAL层具体调用的函数流程为:
首先,sensors_control_open(),只在系统初始化时调用一次。用来初始化control_device结构体。
以下的是每次使用传感器一般经过的流程,注意,是一般而已,有些并不执行
(1)sensors_data_open
(2)get_sensors_list
(3)activate
(4)set_delay
(5)open_data_source
(6)data_open
(7)poll
一直读数据。。。。。。。。。。。
退出时
(8)activate
(9)sensors_control_close
(10)data_close
 
当然其它的细节你们可以继续去研究。也可以在我博客里提出来大家交流和讨论一下!
 
 
阅读(1013) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~