Android C++ 共享内存MemoryHeapBase实现IPC进程通信实际案列

    这篇博文讲的是我如何在自定义的系统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里面

  Android C++ 共享内存MemoryHeapBase实现IPC进程通信实际案列_第1张图片

从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()
{
 


}


这边分别用5个Memory分别存储地磁,陀螺仪,重力,光感,距离传感器数据,为什么5个是由于上层的调用接口决定,其实只要用1个Memory就行采用回调机制就OK了,由于业务逻辑不一样这边不讨论

现在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");
}

到这Client的逻辑就OK了,那我们怎么在自己的系统Service调用呢 当然用JNI了这边看一下JNI吧


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 ()
{

}



到这就结束了 要是看不懂的话就联系我 哈哈


  

  

你可能感兴趣的:(Android,HAL,Android,C++,共享内存Memo)