Android Sensor系统剖析(2.3.5)(上)
2017-03-29 13:25
246 查看
本文希望通过对androidsensor系统的介绍,使大家在了解android sensor系统架构的同时,会对大家阅读和分析其他同类型代码框架有所帮助。
首先看下应用层如何获取sensor数据:
[java] view
plain copy
public class SensorActivity extends Activity, implements SensorEventListener {
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;
public SensorActivity() {
//获取对应服务
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
//获取指定sensor对象
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
protected void onResume() {
super.onResume();
//注册listener用于数据回调
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
}
}
从代码上看,应用首先要使用sensor service名来获取SensorManager对象实例,然后调用其成员函数registerListener并传入listener来得到回调数据。
Sensor service在后台和driver交互获取数据,各个应用连上service获取想要的sensor数据,从如上代码看,没有任何和service交互的代码,这一切都被封装到SensorManager里了。
Android轻量级的系统服务,一般都会运行于systemserver内,sensor service够轻量,当然不能例外。
System server起来时,会创建sensorserivice:
[java] view
plain copy
//frameworks/base/cmds/system_server/library/system_init.cpp
extern "C" status_t system_init()
{
LOGI("Entered system_init()");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());
sp<GrimReaper> 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();
…..
}
通过调用SensorService的静态成员函数instantiate()来初始化并创建sensor service,在详细介绍这个函数的内部行为之前,先来看下SensorService类的声明。
[java] view
plain copy
//frameworks/base/services/sensorservice/Sensorservice.h
class SensorService :
public BinderService<SensorService>,
public BnSensorServer,
protected Thread
{
friend class BinderService<SensorService>;
static const nsecs_t MINIMUM_EVENTS_PERIOD = 1000000; // 1000 Hz
SensorService();
virtual ~SensorService();
virtual void onFirstRef();
// Thread interface
virtual bool threadLoop();
// ISensorServer interface
virtual Vector<Sensor> getSensorList();
virtual sp<ISensorEventConnection> createSensorEventConnection();
virtual status_t dump(int fd, const Vector<String16>& args);
class SensorEventConnection : public BnSensorEventConnection {
virtual ~SensorEventConnection();
virtual void onFirstRef();
virtual sp<SensorChannel> getSensorChannel() const;
virtual status_t enableDisable(int handle, bool enabled);
virtual status_t setEventRate(int handle, nsecs_t ns);
sp<SensorService> const mService;
sp<SensorChannel> const mChannel;
mutable Mutex mConnectionLock;
// protected by SensorService::mLock
SortedVector<int> mSensorInfo;
public:
SensorEventConnection(const sp<SensorService>& service);
status_t sendEvents(sensors_event_t const* buffer, size_t count,
sensors_event_t* scratch = NULL);
bool hasSensor(int32_t handle) const;
bool hasAnySensor() const;
bool addSensor(int32_t handle);
bool removeSensor(int32_t handle);
};
class SensorRecord {
SortedVector< wp<SensorEventConnection> > mConnections;
public:
SensorRecord(const sp<SensorEventConnection>& connection);
bool addConnection(const sp<SensorEventConnection>& connection);
bool removeConnection(const wp<SensorEventConnection>& connection);
size_t getNumConnections() const { return mConnections.size(); }
};
SortedVector< wp<SensorEventConnection> > getActiveConnections() const;
DefaultKeyedVector<int, SensorInterface*> getActiveVirtualSensors() const;
String8 getSensorName(int handle) const;
void recordLastValue(sensors_event_t const * buffer, size_t count);
static void sortEventBuffer(sensors_event_t* buffer, size_t count);
void registerSensor(SensorInterface* sensor);
void registerVirtualSensor(SensorInterface* sensor);
// constants
Vector<Sensor> mSensorList;
DefaultKeyedVector<int, SensorInterface*> mSensorMap;
Vector<SensorInterface *> mVirtualSensorList;
Permission mDump;
status_t mInitCheck;
// protected by mLock
mutable Mutex mLock;
DefaultKeyedVector<int, SensorRecord*> mActiveSensors;
DefaultKeyedVector<int, SensorInterface*> mActiveVirtualSensors;
SortedVector< wp<SensorEventConnection> > mActiveConnections;
// The size of this vector is constant, only the items are mutable
KeyedVector<int32_t, sensors_event_t> mLastEventSeen;
public:
static char const* getServiceName() { return "sensorservice"; }
void cleanupConnection(SensorEventConnection* connection);
status_t enable(const sp<SensorEventConnection>& connection, int handle);
status_t disable(const sp<SensorEventConnection>& connection, int handle);
status_t setEventRate(const sp<SensorEventConnection>& connection, int handle, nsecs_t ns);
};
这个类里面声明了很多函数和变量,我们如何区分哪些是框架性接口函数,哪些是功能辅助性的呢?很简单,看父类就知道了。
[java] view
plain copy
class SensorService :
public BinderService<SensorService>,
public BnSensorServer,
protected Thread
SensorService多重继承自如上三个类,下面简单介绍下:
[java] view
plain copy
BinderService<SensorService>:
模板类,主要功能是提供一些静态函数创建service对象实例,并加到service manager,主要函数有instantiate()等。
Thread:
线程辅助类,调用run创建并启动线程,然后在线程主函数内会回调threadloop函数,所以我们在使用这个它时,最简单得做法是派生自它,然后重写threadloop即可。
BnSensorServer:
这个类派生自ISensorServer,ISensorServer则声明了sensor server和client之间RPC通信接口,具体如下:
class ISensorServer : public IInterface
{
public:
DECLARE_META_INTERFACE(SensorServer);
virtual Vector<Sensor> getSensorList() = 0;
virtual sp<ISensorEventConnection> createSensorEventConnection() = 0;
};
了解了三个父类的功能后,可以推出SensorService的核心功能如下:
1:SensorService:: instantiate()初始化sensorservice并创建线程
2:threadloop在线程启动后,从驱动获取sensor原始数据并通过RPC机制让sensor client获取。
3:BnSensorServer的成员函数负责让sensor client获取sensor信息和创建connection
接下去我们就从这几个函数着手进行详细分析!
先看SensorService:: instantiate():
[java] view
plain copy
//frameworks/base/include/binder/BinderService.h
template<typename SERVICE>
class BinderService
{
public:
static status_t publish() {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
}
static void publishAndJoinThreadPool() {
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
static void instantiate() { publish(); }
static status_t shutdown() {
return NO_ERROR;
}
BinderService是模板类,通过代码可以看到,instantiate直接调用了publish函数,publish函数先获取service manager,然后new了一个SensorService对象,接着调用addService并将sensor service name和新创建sensorservice对象传入。
可能有人会问,调用addService的目的是什么?我们不是通过newSensorService创建sensor后台服务了吗?是的,服务的确已经启动了,但是服务的目的是什么?是供他人使用,你要让他人使用你,前提是得让别人找到你,所以我觉得addService的主要功能有两点:
1:将sensor service信息传入binderkernel,然后binder kernel生成对应于sensor service的handle,并维护之。
2:service manager得到并维护对应servicename和handle供其他应用获取。
举例来说,这就好比你建立了一台设备,你要让别人连接你这台设备,你需要让你的设备与宽带服务器建立拨号连接,然后宽带服务器给你分配ip,别人拿到ip,就能与你建立通信链接了,但是ip太难记了,所以就有了域名
把例子中描述的和android机制对应下,设备对应sensor service,binder kernel对应宽带服务器,ip对应handle,service name对应域名,那service manager对应什么?当然是域名解析服务了。
所以现在就很明了了,客户端要与对应的服务建立通信,只需要通过服务名拿到对应的handle,然后用这个handle组建对应的proxy binder对象即可。
那从代码中呢,如何区分代码是用于创建本地服务还是创建远程代理呢?很简单,看类命名就可以了,以Sensor service举例,本地服务类为BnSensorServer,代理类则为BpSensorServer,开到类的开头没,Bn以为native
binder,Bp则是proxy binder。
Android RPC通信那块就简单介绍到这里,继续往下看。
服务创建时,new了一个SensorService对象实例,那接下去代码肯定走SensorService的构造函数:
[java] view
plain copy
//frameworks/base/services/sensorservice/SensorService.cpp
SensorService::SensorService()
: Thread(false),
mDump("android.permission.DUMP"),
mInitCheck(NO_INIT){
}
看到了,构造函数相当于啥也没做,既然sensorservice对象传给了ServiceManager::AddService,我们来看看AddService的函数声明
[java] view
plain copy
virtual status_t addService( const String16& name, const sp<IBinder>& service);
第二个参数是sp强引用对象,而非单纯的sensor service指针,在第一次构建sp强引用对象时,会调用onFirstRef():
[java] view
plain copy
void SensorService::onFirstRef()
{
LOGD("nuSensorService starting...");
SensorDevice& dev(SensorDevice::getInstance());
if (dev.initCheck() == NO_ERROR) {
uint32_t virtualSensorsNeeds =
(1<<SENSOR_TYPE_GRAVITY) |
(1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
(1<<SENSOR_TYPE_ROTATION_VECTOR);
sensor_t const* list;
int count = dev.getSensorList(&list);
mLastEventSeen.setCapacity(count);
for (int i=0 ; i<count ; i++) {
registerSensor( new HardwareSensor(list[i]) );
switch (list[i].type) {
case SENSOR_TYPE_GRAVITY:
case SENSOR_TYPE_LINEAR_ACCELERATION:
case SENSOR_TYPE_ROTATION_VECTOR:
virtualSensorsNeeds &= ~(1<<list[i].type);
break;
}
}
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
registerVirtualSensor( new GravitySensor(list, count) );
}
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
registerVirtualSensor( new LinearAccelerationSensor(list, count) );
}
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
registerVirtualSensor( new RotationVectorSensor(list, count) );
}
run("SensorService", PRIORITY_URGENT_DISPLAY);
mInitCheck = NO_ERROR;
}
}
这个函数先通过SensorDevice:: getInstance获取SensorDevice对象实例,所以我们接着看SensorDevice的构造函数:
[java] view
plain copy
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 ; i<size_t(count) ; i++) {
mActivationCount.add(list[i].handle, model);
//初始将所有sensor设置为未激活状态
mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
}
}
}
}
通过构造函数可以看出,SensorDevice封装了对SensorHAL层代码的调用,主要包含获取sensor list,poll sensor数据和是否激活指定sensor等,这里就不详细描述。
继续从SensorService::onFirstRef往下走,在得到SensorDevice对象实例后,通过调用dev.getSensorList(&list)获取sensor list,然后调用registersensor将所有sensor加到SensorService的成员变量mSensorList中。
接下去调用run启动线程:
[java] view
plain copy
run("SensorService", PRIORITY_URGENT_DISPLAY);
线程启动后,threadloop会被回调:
[java] view
plain copy
bool SensorService::threadLoop()
{
LOGD("nuSensorService thread starting...");
const size_t numEventMax = 16 * (1 + mVirtualSensorList.size());
sensors_event_t buffer[numEventMax];
sensors_event_t scratch[numEventMax];
SensorDevice& device(SensorDevice::getInstance());
const size_t vcount = mVirtualSensorList.size();
ssize_t count;
do {
//从设备获取已经激活sensor的数据,如果无一sensor被激活,该动作将会被
//阻塞
count = device.poll(buffer, numEventMax);
if (count<0) {
LOGE("sensor poll failed (%s)", strerror(-count));
break;
}
//获取最新的数据
recordLastValue(buffer, count);
// handle virtual sensors
if (count && vcount) {
const DefaultKeyedVector<int, SensorInterface*> virtualSensors(
getActiveVirtualSensors());
const size_t activeVirtualSensorCount = virtualSensors.size();
if (activeVirtualSensorCount) {
size_t k = 0;
for (size_t i=0 ; i<size_t(count) ; i++) {
sensors_event_t const * const event = buffer;
for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
sensors_event_t out;
if (virtualSensors.valueAt(j)->process(&out, event[i])) {
buffer[count + k] = out;
k++;
}
}
}
if (k) {
// record the last synthesized values
recordLastValue(&buffer[count], k);
count += k;
// sort the buffer by time-stamps
sortEventBuffer(buffer, count);
}
}
}
// 得到已有的client连接
const SortedVector< wp<SensorEventConnection> > activeConnections(
getActiveConnections());
size_t numConnections = activeConnections.size();
for (size_t i=0 ; i<numConnections ; i++) {
sp<SensorEventConnection> connection(
activeConnections[i].promote());
if (connection != 0) {
//将sensor数据发往client端
connection->sendEvents(buffer, count, scratch);
}
}
} while (count >= 0 || Thread::exitPending());
LOGW("Exiting SensorService::threadLoop!");
return false;
}
Threadloop主要通过调用sensor HAL函数获取已激活sensor的数据,然后将获取到的数据发往已经建立的connection。
Connection是如何建立的?我们之前描述的三个父类的功能中已经有过描述,ISensorServer定义了client和sensor service的RPC通信接口,client端在得到sensor service代理对象后,通过调用createSensorEventConnection与sensorservice建立connection,先看service端的实现代码:
[java] view
plain copy
sp<ISensorEventConnection> SensorService::createSensorEventConnection()
{
sp<SensorEventConnection> result(new SensorEventConnection(this));
return result;
}
Service端仅仅创建了SensorEventConnection对象实例,然后将这个对象实例传给client端,这里有两个疑问:
1:将实例对象传给client,那是否SensorEventConnection实例也是个RPC服务?
2:sensor service不是保存了active connections,这里也没做保存操作,那在哪里保存?唯一的线索就是构造SensorEventConnection传入的this指针了。
先看第一个疑问,SensorEventConnection是不是RPC服务,看其构造函数先
[java] view
plain copy
class SensorEventConnection : public BnSensorEventConnection
看到没?父类是Bn开头的,说明其是native binder,的确是RPC服务,由于这个服务是私底下咱哥俩偷摸用的,所以就无需加入servicemanager了。
那这个connection是怎么加入sensorservice的action connections的,由于是RPC服务,所以这块动作应该是由client驱动的。
先看ISensorEventConnection
[java] view
plain copy
class ISensorEventConnection : public IInterface
{
public:
DECLARE_META_INTERFACE(SensorEventConnection);
virtual sp<SensorChannel> getSensorChannel() const = 0;
virtual status_t enableDisable(int handle, bool enabled) = 0;
virtual status_t setEventRate(int handle, nsecs_t ns) = 0;
};
共三个接口函数,setEventRate这个应该是设置sensor 数据上报频率的,跟active connection应该没啥关系;getSensorChannel是干嘛用的?等会介绍,但是看名字,也不像!剩下就是enableDisable这个函数了
[java] view
plain copy
status_t SensorService::SensorEventConnection::enableDisable(
int handle, bool enabled)
{
status_t err;
if (enabled) {
err = mService->enable(this, handle);
} else {
err = mService->disable(this, handle);
}
return err;
}
如果是enable,调用sensor service的enable函数
[java] view
plain copy
status_t SensorService::enable(const sp<SensorEventConnection>& connection,
int handle)
{
if (mInitCheck != NO_ERROR)
return mInitCheck;
Mutex::Autolock _l(mLock);
SensorInterface* sensor = mSensorMap.valueFor(handle);
//将对应sensor激活
status_t err = sensor ? sensor->activate(connection.get(), true) : status_t(BAD_VALUE);
if (err == NO_ERROR) {
SensorRecord* rec = mActiveSensors.valueFor(handle);
if (rec == 0) {
rec = new SensorRecord(connection);
mActiveSensors.add(handle, rec);
if (sensor->isVirtual()) {
mActiveVirtualSensors.add(handle, sensor);
}
} else {
if (rec->addConnection(connection)) {
// this sensor is already activated, but we are adding a
// connection that uses it. Immediately send down the last
// known value of the requested sensor.
sensors_event_t scratch;
sensors_event_t& event(mLastEventSeen.editValueFor(handle));
if (event.version == sizeof(sensors_event_t)) {
connection->sendEvents(&event, 1);
}
}
}
if (err == NO_ERROR) {
// connection now active
//将connection加入active connection中
if (connection->addSensor(handle)) {
// the sensor was added (which means it wasn't already there)
// so, see if this connection becomes active
if (mActiveConnections.indexOf(connection) < 0) {
mActiveConnections.add(connection);
}
}
}
}
return err;
}
在这个函数中,激活对应sensor,然后将当前connection加入active connection
到这里,知道了如何创建connection和activeconnection后,还有一个问题就是,sensor数据发送的?大家可能会说,不是通过调用SensorEventConnection ::sendEvents来实现的吗?但是回过头看下ISensorEventConnection的三个函数声明,没有sendEvents这个函数,也就说sendEvents只是一个供sensorservice端用的public函数而已。
[java] view
plain copy
status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t const* buffer, size_t numEvents,
sensors_event_t* scratch)
{
//。。。。
ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t));
if (size == -EAGAIN) {
// the destination doesn't accept events anymore, it's probably
// full. For now, we just drop the events on the floor.
LOGW("dropping %d events on the floor", count);
return size;
}
LOGE_IF(size<0, "dropping %d events on the floor (%s)",
count, strerror(-size));
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
SensorEvent调用SensorChannel的wirte函数发送sensor数据,mChannel是在SensorEventConnection函数中初始化的。
[java] view
plain copy
ssize_t SensorChannel::write(void const* vaddr, size_t size)
{
ssize_t len = ::write(mSendFd, vaddr, size);
if (len < 0)
return -errno;
return len;
}
从这个函数中看到,sensorservice和client端的sensor数据不是通过RPC机制传递的,看下SensorChannel的构造函数
[java] view
plain copy
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);
}
}
明白了,进程间数据共享是通过管道来实现的,现在知道ISensorEventConnection:: getSensorChannel的作用了,用于传递Receive
FD给client的
[java] view
plain copy
status_t SensorChannel::writeToParcel(Parcel* reply) const
{
if (mReceiveFd < 0)
return -EINVAL;
status_t result = reply->writeDupFileDescriptor(mReceiveFd);
close(mReceiveFd);
mReceiveFd = -1;
return result;
}
Client端拿到received FD后,就可以读取sensor数据啦。至此,服务端已经说完了,接下去是客户端部分的讲解。
本文乃原创,转载请注明出处,谢谢。
1:概览
首先看下应用层如何获取sensor数据:[java] view
plain copy
public class SensorActivity extends Activity, implements SensorEventListener {
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;
public SensorActivity() {
//获取对应服务
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
//获取指定sensor对象
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
protected void onResume() {
super.onResume();
//注册listener用于数据回调
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
}
}
从代码上看,应用首先要使用sensor service名来获取SensorManager对象实例,然后调用其成员函数registerListener并传入listener来得到回调数据。
Sensor service在后台和driver交互获取数据,各个应用连上service获取想要的sensor数据,从如上代码看,没有任何和service交互的代码,这一切都被封装到SensorManager里了。
2:Sensor service
Android轻量级的系统服务,一般都会运行于systemserver内,sensor service够轻量,当然不能例外。System server起来时,会创建sensorserivice:
[java] view
plain copy
//frameworks/base/cmds/system_server/library/system_init.cpp
extern "C" status_t system_init()
{
LOGI("Entered system_init()");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());
sp<GrimReaper> 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();
…..
}
通过调用SensorService的静态成员函数instantiate()来初始化并创建sensor service,在详细介绍这个函数的内部行为之前,先来看下SensorService类的声明。
[java] view
plain copy
//frameworks/base/services/sensorservice/Sensorservice.h
class SensorService :
public BinderService<SensorService>,
public BnSensorServer,
protected Thread
{
friend class BinderService<SensorService>;
static const nsecs_t MINIMUM_EVENTS_PERIOD = 1000000; // 1000 Hz
SensorService();
virtual ~SensorService();
virtual void onFirstRef();
// Thread interface
virtual bool threadLoop();
// ISensorServer interface
virtual Vector<Sensor> getSensorList();
virtual sp<ISensorEventConnection> createSensorEventConnection();
virtual status_t dump(int fd, const Vector<String16>& args);
class SensorEventConnection : public BnSensorEventConnection {
virtual ~SensorEventConnection();
virtual void onFirstRef();
virtual sp<SensorChannel> getSensorChannel() const;
virtual status_t enableDisable(int handle, bool enabled);
virtual status_t setEventRate(int handle, nsecs_t ns);
sp<SensorService> const mService;
sp<SensorChannel> const mChannel;
mutable Mutex mConnectionLock;
// protected by SensorService::mLock
SortedVector<int> mSensorInfo;
public:
SensorEventConnection(const sp<SensorService>& service);
status_t sendEvents(sensors_event_t const* buffer, size_t count,
sensors_event_t* scratch = NULL);
bool hasSensor(int32_t handle) const;
bool hasAnySensor() const;
bool addSensor(int32_t handle);
bool removeSensor(int32_t handle);
};
class SensorRecord {
SortedVector< wp<SensorEventConnection> > mConnections;
public:
SensorRecord(const sp<SensorEventConnection>& connection);
bool addConnection(const sp<SensorEventConnection>& connection);
bool removeConnection(const wp<SensorEventConnection>& connection);
size_t getNumConnections() const { return mConnections.size(); }
};
SortedVector< wp<SensorEventConnection> > getActiveConnections() const;
DefaultKeyedVector<int, SensorInterface*> getActiveVirtualSensors() const;
String8 getSensorName(int handle) const;
void recordLastValue(sensors_event_t const * buffer, size_t count);
static void sortEventBuffer(sensors_event_t* buffer, size_t count);
void registerSensor(SensorInterface* sensor);
void registerVirtualSensor(SensorInterface* sensor);
// constants
Vector<Sensor> mSensorList;
DefaultKeyedVector<int, SensorInterface*> mSensorMap;
Vector<SensorInterface *> mVirtualSensorList;
Permission mDump;
status_t mInitCheck;
// protected by mLock
mutable Mutex mLock;
DefaultKeyedVector<int, SensorRecord*> mActiveSensors;
DefaultKeyedVector<int, SensorInterface*> mActiveVirtualSensors;
SortedVector< wp<SensorEventConnection> > mActiveConnections;
// The size of this vector is constant, only the items are mutable
KeyedVector<int32_t, sensors_event_t> mLastEventSeen;
public:
static char const* getServiceName() { return "sensorservice"; }
void cleanupConnection(SensorEventConnection* connection);
status_t enable(const sp<SensorEventConnection>& connection, int handle);
status_t disable(const sp<SensorEventConnection>& connection, int handle);
status_t setEventRate(const sp<SensorEventConnection>& connection, int handle, nsecs_t ns);
};
这个类里面声明了很多函数和变量,我们如何区分哪些是框架性接口函数,哪些是功能辅助性的呢?很简单,看父类就知道了。
[java] view
plain copy
class SensorService :
public BinderService<SensorService>,
public BnSensorServer,
protected Thread
SensorService多重继承自如上三个类,下面简单介绍下:
[java] view
plain copy
BinderService<SensorService>:
模板类,主要功能是提供一些静态函数创建service对象实例,并加到service manager,主要函数有instantiate()等。
Thread:
线程辅助类,调用run创建并启动线程,然后在线程主函数内会回调threadloop函数,所以我们在使用这个它时,最简单得做法是派生自它,然后重写threadloop即可。
BnSensorServer:
这个类派生自ISensorServer,ISensorServer则声明了sensor server和client之间RPC通信接口,具体如下:
class ISensorServer : public IInterface
{
public:
DECLARE_META_INTERFACE(SensorServer);
virtual Vector<Sensor> getSensorList() = 0;
virtual sp<ISensorEventConnection> createSensorEventConnection() = 0;
};
了解了三个父类的功能后,可以推出SensorService的核心功能如下:
1:SensorService:: instantiate()初始化sensorservice并创建线程
2:threadloop在线程启动后,从驱动获取sensor原始数据并通过RPC机制让sensor client获取。
3:BnSensorServer的成员函数负责让sensor client获取sensor信息和创建connection
接下去我们就从这几个函数着手进行详细分析!
先看SensorService:: instantiate():
[java] view
plain copy
//frameworks/base/include/binder/BinderService.h
template<typename SERVICE>
class BinderService
{
public:
static status_t publish() {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
}
static void publishAndJoinThreadPool() {
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
static void instantiate() { publish(); }
static status_t shutdown() {
return NO_ERROR;
}
BinderService是模板类,通过代码可以看到,instantiate直接调用了publish函数,publish函数先获取service manager,然后new了一个SensorService对象,接着调用addService并将sensor service name和新创建sensorservice对象传入。
可能有人会问,调用addService的目的是什么?我们不是通过newSensorService创建sensor后台服务了吗?是的,服务的确已经启动了,但是服务的目的是什么?是供他人使用,你要让他人使用你,前提是得让别人找到你,所以我觉得addService的主要功能有两点:
1:将sensor service信息传入binderkernel,然后binder kernel生成对应于sensor service的handle,并维护之。
2:service manager得到并维护对应servicename和handle供其他应用获取。
举例来说,这就好比你建立了一台设备,你要让别人连接你这台设备,你需要让你的设备与宽带服务器建立拨号连接,然后宽带服务器给你分配ip,别人拿到ip,就能与你建立通信链接了,但是ip太难记了,所以就有了域名
把例子中描述的和android机制对应下,设备对应sensor service,binder kernel对应宽带服务器,ip对应handle,service name对应域名,那service manager对应什么?当然是域名解析服务了。
所以现在就很明了了,客户端要与对应的服务建立通信,只需要通过服务名拿到对应的handle,然后用这个handle组建对应的proxy binder对象即可。
那从代码中呢,如何区分代码是用于创建本地服务还是创建远程代理呢?很简单,看类命名就可以了,以Sensor service举例,本地服务类为BnSensorServer,代理类则为BpSensorServer,开到类的开头没,Bn以为native
binder,Bp则是proxy binder。
Android RPC通信那块就简单介绍到这里,继续往下看。
服务创建时,new了一个SensorService对象实例,那接下去代码肯定走SensorService的构造函数:
[java] view
plain copy
//frameworks/base/services/sensorservice/SensorService.cpp
SensorService::SensorService()
: Thread(false),
mDump("android.permission.DUMP"),
mInitCheck(NO_INIT){
}
看到了,构造函数相当于啥也没做,既然sensorservice对象传给了ServiceManager::AddService,我们来看看AddService的函数声明
[java] view
plain copy
virtual status_t addService( const String16& name, const sp<IBinder>& service);
第二个参数是sp强引用对象,而非单纯的sensor service指针,在第一次构建sp强引用对象时,会调用onFirstRef():
[java] view
plain copy
void SensorService::onFirstRef()
{
LOGD("nuSensorService starting...");
SensorDevice& dev(SensorDevice::getInstance());
if (dev.initCheck() == NO_ERROR) {
uint32_t virtualSensorsNeeds =
(1<<SENSOR_TYPE_GRAVITY) |
(1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
(1<<SENSOR_TYPE_ROTATION_VECTOR);
sensor_t const* list;
int count = dev.getSensorList(&list);
mLastEventSeen.setCapacity(count);
for (int i=0 ; i<count ; i++) {
registerSensor( new HardwareSensor(list[i]) );
switch (list[i].type) {
case SENSOR_TYPE_GRAVITY:
case SENSOR_TYPE_LINEAR_ACCELERATION:
case SENSOR_TYPE_ROTATION_VECTOR:
virtualSensorsNeeds &= ~(1<<list[i].type);
break;
}
}
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
registerVirtualSensor( new GravitySensor(list, count) );
}
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
registerVirtualSensor( new LinearAccelerationSensor(list, count) );
}
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
registerVirtualSensor( new RotationVectorSensor(list, count) );
}
run("SensorService", PRIORITY_URGENT_DISPLAY);
mInitCheck = NO_ERROR;
}
}
这个函数先通过SensorDevice:: getInstance获取SensorDevice对象实例,所以我们接着看SensorDevice的构造函数:
[java] view
plain copy
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 ; i<size_t(count) ; i++) {
mActivationCount.add(list[i].handle, model);
//初始将所有sensor设置为未激活状态
mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
}
}
}
}
通过构造函数可以看出,SensorDevice封装了对SensorHAL层代码的调用,主要包含获取sensor list,poll sensor数据和是否激活指定sensor等,这里就不详细描述。
继续从SensorService::onFirstRef往下走,在得到SensorDevice对象实例后,通过调用dev.getSensorList(&list)获取sensor list,然后调用registersensor将所有sensor加到SensorService的成员变量mSensorList中。
接下去调用run启动线程:
[java] view
plain copy
run("SensorService", PRIORITY_URGENT_DISPLAY);
线程启动后,threadloop会被回调:
[java] view
plain copy
bool SensorService::threadLoop()
{
LOGD("nuSensorService thread starting...");
const size_t numEventMax = 16 * (1 + mVirtualSensorList.size());
sensors_event_t buffer[numEventMax];
sensors_event_t scratch[numEventMax];
SensorDevice& device(SensorDevice::getInstance());
const size_t vcount = mVirtualSensorList.size();
ssize_t count;
do {
//从设备获取已经激活sensor的数据,如果无一sensor被激活,该动作将会被
//阻塞
count = device.poll(buffer, numEventMax);
if (count<0) {
LOGE("sensor poll failed (%s)", strerror(-count));
break;
}
//获取最新的数据
recordLastValue(buffer, count);
// handle virtual sensors
if (count && vcount) {
const DefaultKeyedVector<int, SensorInterface*> virtualSensors(
getActiveVirtualSensors());
const size_t activeVirtualSensorCount = virtualSensors.size();
if (activeVirtualSensorCount) {
size_t k = 0;
for (size_t i=0 ; i<size_t(count) ; i++) {
sensors_event_t const * const event = buffer;
for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
sensors_event_t out;
if (virtualSensors.valueAt(j)->process(&out, event[i])) {
buffer[count + k] = out;
k++;
}
}
}
if (k) {
// record the last synthesized values
recordLastValue(&buffer[count], k);
count += k;
// sort the buffer by time-stamps
sortEventBuffer(buffer, count);
}
}
}
// 得到已有的client连接
const SortedVector< wp<SensorEventConnection> > activeConnections(
getActiveConnections());
size_t numConnections = activeConnections.size();
for (size_t i=0 ; i<numConnections ; i++) {
sp<SensorEventConnection> connection(
activeConnections[i].promote());
if (connection != 0) {
//将sensor数据发往client端
connection->sendEvents(buffer, count, scratch);
}
}
} while (count >= 0 || Thread::exitPending());
LOGW("Exiting SensorService::threadLoop!");
return false;
}
Threadloop主要通过调用sensor HAL函数获取已激活sensor的数据,然后将获取到的数据发往已经建立的connection。
Connection是如何建立的?我们之前描述的三个父类的功能中已经有过描述,ISensorServer定义了client和sensor service的RPC通信接口,client端在得到sensor service代理对象后,通过调用createSensorEventConnection与sensorservice建立connection,先看service端的实现代码:
[java] view
plain copy
sp<ISensorEventConnection> SensorService::createSensorEventConnection()
{
sp<SensorEventConnection> result(new SensorEventConnection(this));
return result;
}
Service端仅仅创建了SensorEventConnection对象实例,然后将这个对象实例传给client端,这里有两个疑问:
1:将实例对象传给client,那是否SensorEventConnection实例也是个RPC服务?
2:sensor service不是保存了active connections,这里也没做保存操作,那在哪里保存?唯一的线索就是构造SensorEventConnection传入的this指针了。
先看第一个疑问,SensorEventConnection是不是RPC服务,看其构造函数先
[java] view
plain copy
class SensorEventConnection : public BnSensorEventConnection
看到没?父类是Bn开头的,说明其是native binder,的确是RPC服务,由于这个服务是私底下咱哥俩偷摸用的,所以就无需加入servicemanager了。
那这个connection是怎么加入sensorservice的action connections的,由于是RPC服务,所以这块动作应该是由client驱动的。
先看ISensorEventConnection
[java] view
plain copy
class ISensorEventConnection : public IInterface
{
public:
DECLARE_META_INTERFACE(SensorEventConnection);
virtual sp<SensorChannel> getSensorChannel() const = 0;
virtual status_t enableDisable(int handle, bool enabled) = 0;
virtual status_t setEventRate(int handle, nsecs_t ns) = 0;
};
共三个接口函数,setEventRate这个应该是设置sensor 数据上报频率的,跟active connection应该没啥关系;getSensorChannel是干嘛用的?等会介绍,但是看名字,也不像!剩下就是enableDisable这个函数了
[java] view
plain copy
status_t SensorService::SensorEventConnection::enableDisable(
int handle, bool enabled)
{
status_t err;
if (enabled) {
err = mService->enable(this, handle);
} else {
err = mService->disable(this, handle);
}
return err;
}
如果是enable,调用sensor service的enable函数
[java] view
plain copy
status_t SensorService::enable(const sp<SensorEventConnection>& connection,
int handle)
{
if (mInitCheck != NO_ERROR)
return mInitCheck;
Mutex::Autolock _l(mLock);
SensorInterface* sensor = mSensorMap.valueFor(handle);
//将对应sensor激活
status_t err = sensor ? sensor->activate(connection.get(), true) : status_t(BAD_VALUE);
if (err == NO_ERROR) {
SensorRecord* rec = mActiveSensors.valueFor(handle);
if (rec == 0) {
rec = new SensorRecord(connection);
mActiveSensors.add(handle, rec);
if (sensor->isVirtual()) {
mActiveVirtualSensors.add(handle, sensor);
}
} else {
if (rec->addConnection(connection)) {
// this sensor is already activated, but we are adding a
// connection that uses it. Immediately send down the last
// known value of the requested sensor.
sensors_event_t scratch;
sensors_event_t& event(mLastEventSeen.editValueFor(handle));
if (event.version == sizeof(sensors_event_t)) {
connection->sendEvents(&event, 1);
}
}
}
if (err == NO_ERROR) {
// connection now active
//将connection加入active connection中
if (connection->addSensor(handle)) {
// the sensor was added (which means it wasn't already there)
// so, see if this connection becomes active
if (mActiveConnections.indexOf(connection) < 0) {
mActiveConnections.add(connection);
}
}
}
}
return err;
}
在这个函数中,激活对应sensor,然后将当前connection加入active connection
到这里,知道了如何创建connection和activeconnection后,还有一个问题就是,sensor数据发送的?大家可能会说,不是通过调用SensorEventConnection ::sendEvents来实现的吗?但是回过头看下ISensorEventConnection的三个函数声明,没有sendEvents这个函数,也就说sendEvents只是一个供sensorservice端用的public函数而已。
[java] view
plain copy
status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t const* buffer, size_t numEvents,
sensors_event_t* scratch)
{
//。。。。
ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t));
if (size == -EAGAIN) {
// the destination doesn't accept events anymore, it's probably
// full. For now, we just drop the events on the floor.
LOGW("dropping %d events on the floor", count);
return size;
}
LOGE_IF(size<0, "dropping %d events on the floor (%s)",
count, strerror(-size));
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
SensorEvent调用SensorChannel的wirte函数发送sensor数据,mChannel是在SensorEventConnection函数中初始化的。
[java] view
plain copy
ssize_t SensorChannel::write(void const* vaddr, size_t size)
{
ssize_t len = ::write(mSendFd, vaddr, size);
if (len < 0)
return -errno;
return len;
}
从这个函数中看到,sensorservice和client端的sensor数据不是通过RPC机制传递的,看下SensorChannel的构造函数
[java] view
plain copy
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);
}
}
明白了,进程间数据共享是通过管道来实现的,现在知道ISensorEventConnection:: getSensorChannel的作用了,用于传递Receive
FD给client的
[java] view
plain copy
status_t SensorChannel::writeToParcel(Parcel* reply) const
{
if (mReceiveFd < 0)
return -EINVAL;
status_t result = reply->writeDupFileDescriptor(mReceiveFd);
close(mReceiveFd);
mReceiveFd = -1;
return result;
}
Client端拿到received FD后,就可以读取sensor数据啦。至此,服务端已经说完了,接下去是客户端部分的讲解。
本文乃原创,转载请注明出处,谢谢。
相关文章推荐
- Android Sensor系统剖析(2.3.5)(上)
- Android Sensor系统剖析(2.3.5)(上)
- Android Sensor系统剖析(4.0)(下)
- Android Sensor系统剖析(4.0)(下)
- [置顶] Android Sensor系统剖析(4.0)(下)
- Android Sensor系统剖析(4.0)(下)
- Android 图形系统剖析
- Android之传感器系统(Gsensor)
- Android文件系统深入剖析
- 基于android2.3.5系统:开天辟地Android启动机制[一]
- Android文件系统深入剖析
- android系统底层到应用层全面剖析
- Android 图形系统剖析
- 深入理解Android Sensor系统 (4.0)
- Android Sensor传感器系统架构初探
- Android文件系统深入剖析
- Android 图形系统剖析
- Android Sensor传感器系统架构初探
- Android 图形系统剖析