这篇博文讲的是我如何在自定义的系统Service通过MemoryHeapBase共享内存方式实现IPC访问SensorService的数据
调用方式通过JNI拉起动态库的形式
一:我们要做Android系统的Sensorservice.cpp添加共享内存
修改文件地址/frameworks/native/services/sensorservice/SensorService.cpp
/frameworks/native/include/gui/ISensorServer.h
/frameworks/native/include/gui/SensorManager.h
/frameworks/native/libs/gui/ISensorServer.cpp
1:先看一下SensorService添加获得共享内存的方法在ISensorServer.h里面添加
class ISensorServer : public IInterface
{
public:
DECLARE_META_INTERFACE(SensorServer);
virtual Vector getSensorList(const String16& opPackageName) = 0;
virtual sp createSensorEventConnection(const String8& packageName,
int mode, const String16& opPackageName) = 0;
virtual int32_t isDataInjectionEnabled() = 0;
virtual sp getSensorSharedMemory(int type) = 0;
};
getSensorSharedMemory()函数
2:SensorService作为Server端在threadLoop()里面把从HAL收到的Sensor数据丢到Memory里面
从Diff看到我的修改记录,这边由于是封装在动态库里,所以我们看一下自己封装的动态库的源码
//
// Created by Administrator on 2017/12/11.
//
#ifndef SENSORNATIVE_SENSORSERVICEAPI_H
#define SENSORNATIVE_SENSORSERVICEAPI_H
#include
#include
#include
#include "SensorUtil.h"
using namespace android;
class SensorServiceApi :public RefBase{
private:
virtual void onFirstRef();
sp _mGyroHeapBase;
sp _mGyroMemory;
SensorEvent* _mGyroBuffer;
sp _mAcclHeapBase;
sp _mAcclMemory;
SensorEvent* _mAcclBuffer;
sp _mMagHeapBase;
sp _mMagMemory;
SensorEvent* _mMagBuffer;
sp _mLightHeapBase;
sp _mLightMemory;
SensorEvent* _mLightBuffer;
sp _mProxiMityHeapBase;
sp _mProxiMityMemory;
SensorEvent* _mProxiMityBuffer;
protected:
public:
SensorServiceApi();
virtual ~SensorServiceApi();
virtual sp getSharedMemory(int type);
void handlerEvent(sensors_event_t * data);
};
#endif //SENSORNATIVE_SENSORSERVICEAPI_H
//
// Created by Administrator on 2017/12/11.
//
#include
SensorServiceApi::SensorServiceApi()
{
}
void SensorServiceApi::onFirstRef()
{
int bufsize = sizeof(SensorEvent);
_mMagHeapBase = new MemoryHeapBase(bufsize, 0, "nvr_sensorevent_magnetic_buffer");
if(_mMagHeapBase != NULL)
{
_mMagMemory = new MemoryBase(_mMagHeapBase, 0, bufsize);
_mMagBuffer = (SensorEvent*)_mMagMemory->pointer();
if(_mMagBuffer != NULL)
{
memset(_mMagBuffer,0,bufsize);
}
}
_mGyroHeapBase = new MemoryHeapBase(bufsize, 0, "nvr_sensorevent_gyro_buffer");
if(_mGyroHeapBase != NULL)
{
_mGyroMemory = new MemoryBase(_mGyroHeapBase, 0, bufsize);
_mGyroBuffer = (SensorEvent*)_mGyroMemory->pointer();
if(_mGyroBuffer != NULL)
{
memset(_mGyroBuffer,0,bufsize);
}
}
_mAcclHeapBase = new MemoryHeapBase(bufsize, 0, "nvr_sensorevent_accl_buffer");
if(_mAcclHeapBase != NULL)
{
_mAcclMemory = new MemoryBase(_mAcclHeapBase, 0, bufsize);
_mAcclBuffer = (SensorEvent*)_mAcclMemory->pointer();
if(_mAcclBuffer != NULL)
{
memset(_mAcclBuffer,0,bufsize);
}
}
_mLightHeapBase = new MemoryHeapBase(bufsize, 0, "nvr_sensorevent_light_buffer");
if(_mLightHeapBase != NULL)
{
_mLightMemory = new MemoryBase(_mLightHeapBase, 0, bufsize);
_mLightBuffer = (SensorEvent*)_mLightMemory->pointer();
if(_mLightBuffer != NULL)
{
memset(_mLightBuffer,0,bufsize);
}
}
_mProxiMityHeapBase = new MemoryHeapBase(bufsize, 0, "nvr_sensorevent_proxi_buffer");
if(_mProxiMityHeapBase != NULL)
{
_mProxiMityMemory = new MemoryBase(_mProxiMityHeapBase, 0, bufsize);
_mProxiMityBuffer = (SensorEvent*)_mProxiMityMemory->pointer();
if(_mProxiMityBuffer != NULL)
{
memset(_mProxiMityBuffer,0,bufsize);
}
}
}
sp SensorServiceApi::getSharedMemory(int type)
{
sp temp;
switch(type)
{
case ASENSOR_TYPE_ACCELEROMETER:
temp = _mAcclMemory;
break;
case ASENSOR_TYPE_GYROSCOPE:
temp = _mGyroMemory;
break;
case ASENSOR_TYPE_MAGNETIC_FIELD:
temp = _mMagMemory;
break;
case ASENSOR_TYPE_LIGHT:
temp = _mLightMemory;
break;
case ASENSOR_TYPE_PROXIMITY:
temp = _mProxiMityMemory;
break;
}
return temp;
}
void SensorServiceApi::handlerEvent(sensors_event_t * data)
{
SensorEvent tempSensorEvent;
if(data != NULL)
{
tempSensorEvent.type = data->type;
//ALOGE("shao2 tempvalue, value0 = %ld -- value1 = %ld ---value2 = %ld\n",data->data[0] ,tempSensorEvent.dataArray[1] ,tempSensorEvent.dataArray[2]);
memcpy(tempSensorEvent.dataArray,data->data,sizeof(float) * 16);
//ALOGE("shao,tempvalue type = %d, value0 = %f -- value1 = %f ---value2 = %f\n", tempSensorEvent.type ,tempSensorEvent.dataArray[0] ,tempSensorEvent.dataArray[1] ,tempSensorEvent.dataArray[2]);
switch(data->type)
{
case ASENSOR_TYPE_ACCELEROMETER:
if(_mAcclBuffer != NULL)
{
memcpy(_mAcclBuffer,&tempSensorEvent,sizeof(SensorEvent));
//ALOGE("shaoaccltempvalue value0 = %f -- value1 = %f ---value2 = %f\n",tempSensorEvent.dataArray[0] ,tempSensorEvent.dataArray[1] ,tempSensorEvent.dataArray[2]);
}
break;
case ASENSOR_TYPE_GYROSCOPE:
if(_mGyroBuffer != NULL)
{
memcpy(_mGyroBuffer,&tempSensorEvent,sizeof(SensorEvent));
//ALOGE("shaogyrotempvalue value0 = %f -- value1 = %f ---value2 = %f\n",tempSensorEvent.dataArray[0] ,tempSensorEvent.dataArray[1] ,tempSensorEvent.dataArray[2]);
}
break;
case ASENSOR_TYPE_MAGNETIC_FIELD:
if(_mMagBuffer != NULL)
{
memcpy(_mMagBuffer,&tempSensorEvent,sizeof(SensorEvent));
//ALOGE("shaomagtempvalue value0 = %f -- value1 = %f ---value2 = %f\n",tempSensorEvent.dataArray[0] ,tempSensorEvent.dataArray[1] ,tempSensorEvent.dataArray[2]);
}
break;
case ASENSOR_TYPE_LIGHT:
if(_mLightBuffer != NULL)
{
memcpy(_mLightBuffer,&tempSensorEvent,sizeof(SensorEvent));
//ALOGE("shaolighttempvalue value0 = %f -- value1 = %f ---value2 = %f\n",tempSensorEvent.dataArray[0] ,tempSensorEvent.dataArray[1] ,tempSensorEvent.dataArray[2]);
}
break;
case ASENSOR_TYPE_PROXIMITY:
if(_mProxiMityBuffer != NULL)
{
memcpy(_mProxiMityBuffer,&tempSensorEvent,sizeof(SensorEvent));
//ALOGE("shaoproxitempvalue value0 = %f -- value1 = %f ---value2 = %f\n" ,tempSensorEvent.dataArray[0] ,tempSensorEvent.dataArray[1] ,tempSensorEvent.dataArray[2]);
}
break;
}
}
}
SensorServiceApi::~SensorServiceApi()
{
}
现在SensorService就搞定了,也是是IPC的Server端解决了,现在看一下Client端
二:我们要让自己的Service远程调用共享内存获得数据
我这边封装的动态库是可以给Server端和Client端共用的,这边看一下Client的调用逻辑
/*
*Created by Zhongqi.Shao on 2017/11/29.
*SDK合理的情况就是只有1个通道1个looper去轮询每次registerListener的时候更新listener地址
*/
#ifndef SENSORNATIVE_SENSORCLIENT_H
#define SENSORNATIVE_SENSORCLIENT_H
#include
#include
#include
#include
#include
#include
#include
#define PACKAGE_NAME "SensorNative"
using namespace android;
class SensorClient:public RefBase{
private:
SensorManager* _sensorManager;
//packageName对应servicea的Key析构时自动清理connection
sp _sensorEventQueue;
virtual void onFirstRef();
public:
SensorClient();
virtual ~SensorClient();
SensorManager& getNativeSensorManager(const char* packageName);
//通过type获得senosr
Sensor const* getDefaultSensor(int type);
int nativeDisableSensor(int type);
int nativeEnableSensor(int type, int rate_us);
sp getSharedMemory(int type);
};
#endif //SENSORNATIVE_SENSORCLIENT_H
//
// Created by Zhongqi.Shao on 2017/11/29.
//
#include
#include
#include
SensorClient::SensorClient()
{
}
void SensorClient::onFirstRef()
{
ALOGD("shao first");
_sensorManager = &getNativeSensorManager("SensorNative");
_sensorEventQueue = _sensorManager->createEventQueue(String8("SensorNative"));
}
SensorManager& SensorClient::getNativeSensorManager(const char* packageName)
{
return SensorManager::getInstanceForPackage(String16(packageName));
}
Sensor const* SensorClient::getDefaultSensor(int type)
{
return _sensorManager->getDefaultSensor(type);
}
int SensorClient::nativeEnableSensor(int type, int rate_us)
{
Sensor const* tempSensor = getDefaultSensor(type);
if(tempSensor == NULL)
{
return -1;
}
int handle = tempSensor->getHandle();
ALOGE("shao native enable sensor type = %d\n",handle);
return _sensorEventQueue->enableSensor(handle, rate_us, 0, 0);
}
int SensorClient::nativeDisableSensor(int type)
{
Sensor const* tempSensor = getDefaultSensor(type);
int handle = tempSensor->getHandle();
return _sensorEventQueue->disableSensor(handle);
}
sp SensorClient::getSharedMemory(int type)
{
return _sensorManager->getSharedMemory(type);
}
SensorClient::~SensorClient()
{
_sensorEventQueue.clear();
ALOGE("shao sensorclient xigou");
}
extern "C"
JNIEXPORT void JNICALL jni_registerClient
(JNIEnv * env, jobject obj,jintArray sensorsArgs,jobject objNibiruService, jfloatArray strach)
{
ISensorInterface interface;
interface.initClient();
jint* typeArray = env->GetIntArrayElements(sensorsArgs,nullptr);
jint length = env->GetArrayLength(sensorsArgs);
interface.enableSensors(length,typeArray);
ALOGE("shao jniEnableSensors");
}
extern "C"
JNIEXPORT jfloatArray JNICALL jni_getSensorData
(JNIEnv *env, jobject obj,jint sensorType)
{
ISensorInterface interface;
sp memory = interface.getSharedMemory(sensorType);
if(memory.get() == NULL || memory->pointer() == NULL)
{
ALOGE("shao shared_pointer null");
return NULL;
}else
{
SensorEvent* pointer = (SensorEvent*)(memory->pointer());
if(pointer->type == sensorType)
{
jfloatArray result = env->NewFloatArray(16);
env->SetFloatArrayRegion(result, 0, 16, pointer->dataArray);
return result;
}else
{
ALOGE("shao need type = %d, src type = %d\n",sensorType,pointer->type);
return NULL;
}
}
}
extern "C"
JNIEXPORT void JNICALL jni_unregisterClient
(JNIEnv * env, jobject obj,jintArray sensorsArgs)
{
ISensorInterface interface;
jint* typeArray = env->GetIntArrayElements(sensorsArgs,nullptr);
jint length = env->GetArrayLength(sensorsArgs);
interface.disableSensor(length,typeArray);
interface.destroyClient();
ALOGE("shao jniDisableSensors");
}
最后看一下JNI到动态库的接口类吧
//
// Created by Administrator on 2017/11/29.
//
#include
#include
#include
#include
API_EXPORT void ISensorInterface::initClient()
{
if(spSensor.get() == NULL)
{
spSensor = new SensorClient();
ALOGD("shao initClient");
}
}
API_EXPORT void ISensorInterface::enableSensors(int count,int* typeArray)
{
if(spSensor.get() != NULL && typeArray != NULL)
{
//spSensor->registerListener(callBackListener);
for (int i = 0; i < count; i++)
{
int type = typeArray[i];
spSensor->nativeEnableSensor(type,ms2ns(10));
ALOGE("shao native register2 and type = %d,count = %d\n",type,count);
}
}
}
API_EXPORT void ISensorInterface::destroyClient()
{
if(spSensor.get() != NULL)
{
spSensor.clear();
}
}
API_EXPORT void ISensorInterface::disableSensor(int count,int* typeArray)
{
if(spSensor.get() != NULL && typeArray != NULL)
{
for (int i = 0; i < count; i++)
{
int type = typeArray[i];
spSensor->nativeDisableSensor(type);
ALOGE("shao native disable sensor = %d,count = %d\n",type,count);
}
}
}
API_EXPORT sp ISensorInterface::getSharedMemory(int type)
{
if(spSensor.get() != NULL)
{
return spSensor->getSharedMemory(type);
}
return NULL;
}
ISensorInterface::~ISensorInterface ()
{
}