Sensor 代碼流程分析

來源:互聯網
上載者:User

本文針對android 2.3 版本的sensor從應用到hal層介面進行逐層分析。4.0的代碼也拿到了,不過還沒有來得及進行分析。

一、應用程式,一般的應用程式寫法:

package com.sensors.testSensor; 

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 testSensor extends Activity {

    SensorManager sensormanager = null;

    Sensor lightSensor = 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);   // 擷取SensorManager 用戶端對象

    lightSensor = sensormanager.getDefaultSensor(Sensor.TYPE_LIGHT);   // 擷取LIGTH感應器,或者直接傳入Sensor.TYPE_ALL 擷取所有的sensorList

    accTextView = (TextView)findViewById(R.id.textview_name);

    }

   

    SensorEventListener lsn = new SensorEventListener() {  

        public void onSensorChanged(SensorEvent e) {

      
if (e.sensor == lightSensor) {

             Log.d("sensor", "found light sensor");

                accTextView.setText("data is " + e.values[0]);

        }

        }  

 

        public void onAccuracyChanged(Sensor s, int accuracy) {  

//TODO

        }  

    };    

    @Override   

    protected void onResume() {       //註冊感應器

    
super.onResume();      // register this class as a listener for the orientation and accelerometer sensors       

    
sensormanager.registerListener(lsn, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);

    }       

    @Override   

    protected void onStop() {        // unregister listener        

    
sensormanager.unregisterListener(lsn, lightSensor);

    
super.onStop();   

    }  

}


總之,應用中實現如下兩個重要回呼函數即可捕獲sensor data資料:

public void onSensorChanged(SensorEvent e)
public void onAccuracyChanged(Sensor s, int accuracy)


首先來張整體模組圖,讓大家有個總體認識 :



二、分析用戶端的實現

首先擷取到所有sensor列表
public List<Sensor> getSensorList(int type)

加入到ListenerDelegate監控列表中
public boolean registerListener(SensorListener listener, int sensors)

l = new ListenerDelegate(listener, sensor, handler);
sListeners.add(l);

使能或禁能調用(啟動哪些sensor採集資料):
private boolean enableSensorLocked(Sensor sensor, int delay)

sensors_enable_sensor --> jni (sensors_enable_sensor) -->  
利用binder調用sensorservice 的 enableDisable函數

擷取資料:
final int sensor = sensors_data_poll(sQueue, values, status, timestamp);
--> jni (sensors_data_poll) --> 調用sensordevice中的ssize_t poll(sensors_event_t* buffer, size_t count)函數

不過這個中間有個sensorchannel的機制,這裡充分利用了pipe機制
SensorChannel::SensorChannel()
    : mSendFd(-1), mReceiveFd(-1)
{
    int fds[2];
    if (pipe(fds) == 0) {
        mReceiveFd = fds[0];
        mSendFd = fds[1];
        fcntl(mReceiveFd, F_SETFL, O_NONBLOCK);
        fcntl(mSendFd, F_SETFL, O_NONBLOCK);
    }
}

/* sensorservice 往管道中寫入資料 */
ssize_t SensorChannel::write(void const* vaddr, size_t size)
{
    ssize_t len = ::write(mSendFd, vaddr, size);
    if (len < 0)
        return -errno;
    return len;
}

/* 從管道中讀取資料 */
ssize_t SensorChannel::read(void* vaddr, size_t size)
{
    ssize_t len = ::read(mReceiveFd, vaddr, size);
    if (len < 0)
        return -errno;
    return len;
}


對於SensorManager.cpp 說明一下:

首先擷取sensorService的服務:

    const String16 name("sensorservice");
    while (getService(name, &mSensorServer) != NO_ERROR) {
        usleep(250000);
    }


三、分析服務端的實現

sensorService的註冊:

system_init.cpp 

extern "C" status_t system_init()
{  

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

}

-->

static void instantiate() { publish(); }

    static status_t publish() {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
    }


利用BinderService的publish方法進行註冊,所以可以在這裡看到:

class SensorService :
        public BinderService<SensorService>,
        public BnSensorServer,
        protected Thread

重要的一些函數說明:

加入監控的sensor裝置
virtual status_t enableDisable(int handle, bool enabled);
--->
sensor->activate(connection.get(), true)
-->
SensorRecord * rec = new SensorRecord(connection);;
rec->addConnection(connection) --> connection->sendEvents(&event, 1);

擷取sensordevice的資料並寫入sensorchannel:
bool SensorService::threadLoop()
{
while(1){
/* poll sensor device data */
count = device.poll(buffer, numEventMax);

recordLastValue(buffer, count);

// send our events to clients...
connection->sendEvents(buffer, count, scratch);
...
}
}


四、用戶端與服務端通訊過程

利用binder機制即可,列出重要的代碼:

class ISensorEventConnection : public IInterface  // 用於用戶端
{
public:
    DECLARE_META_INTERFACE(SensorEventConnection);     // 聲明一個SensorEventConnection模板

...

}


class BnSensorEventConnection : public BnInterface<ISensorEventConnection> // 服務端代碼

{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

實現中重要的實現:

IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection");


status_t BnSensorEventConnection::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {

case XXX:

break;

    }

return BBinder::onTransact(code, data, reply, flags);

}


ok, 對於binder機制的問題可以參考, 在此就不詳細介紹了:

http://blog.csdn.net/andyhuabing/article/details/7004593

五、 HAL層介面

上層調用類 SensorDevice:

主要調用邏輯:

   // 載入動態庫 

    status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
            (hw_module_t const**)&mSensorModule);

  // 開啟sensor 裝置

  sensors_open(&mSensorModule->common, &mSensorDevice);


 最重要的四個hal介面函數:

    int (*get_sensors_list)(struct sensors_module_t* module,
            struct sensor_t const** list);  // sensorList列表資訊

    int (*activate)(struct sensors_poll_device_t *dev,
            int handle, int enabled);    int (*setDelay)(struct sensors_poll_device_t *dev,
            int handle, int64_t ns);   // 使用及禁止

    int (*setDelay)(struct sensors_poll_device_t *dev,
            int handle, int64_t ns);  // 延時或採樣頻率

    int (*poll)(struct sensors_poll_device_t *dev,
            sensors_event_t* data, int count);  // poll資料


這塊代碼實現可以參考:

device\htc\passion-common\libsensors

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.