本文针对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
原文地址:点击打开链接