本帖最后由 jackson 于 2016-3-2 19:12 编辑
android中基本的架构都是C/S层架构,客户端提供调用接口,实现工作由服务端完成,那么Camera也同样满
足此条件:Client进程虽然不曾拥有任何实质的Camera数据,但是service端为它提供了丰富的接口,它可以轻松
的获得Camera数据的地址,然后处理这些数据。两者通过Binder进行通讯。
从底层驱动到APP的流程:
1.camera底层驱动
主要是初始化camera芯片以及具体的交互功能,然后创建设备节点来与上层交互。
Camera硬件驱动提供的接口:
static long CAMERA_HW_Ioctl(
struct file * a_pstFile,
unsigned int a_u4Command,
unsigned long a_u4Param
)
{
int i4RetValue = 0;
void * pBuff = NULL;
u32 *pIdx = NULL;
mutex_lock(&kdCam_Mutex);
if(_IOC_NONE == _IOC_DIR(a_u4Command)) {
}
else {
pBuff = kmalloc(_IOC_SIZE(a_u4Command),GFP_KERNEL);
if(NULL == pBuff) {
PK_DBG("[CAMERA SENSOR] ioctl allocate mem failed\n");
i4RetValue = -ENOMEM;
goto CAMERA_HW_Ioctl_EXIT;
}
if(_IOC_WRITE & _IOC_DIR(a_u4Command)){
if(copy_from_user(pBuff , (void *) a_u4Param, _IOC_SIZE(a_u4Command))) {
kfree(pBuff);
PK_DBG("[CAMERA SENSOR] ioctl copy from user failed\n");
i4RetValue = -EFAULT;
goto CAMERA_HW_Ioctl_EXIT;
}
}
}
pIdx = (u32*)pBuff;
switch(a_u4Command) {
#if 0
case KDIMGSENSORIOC_X_POWER_ON:
i4RetValue = kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) *pIdx, true, CAMERA_HW_DRVNAME);
break;
case KDIMGSENSORIOC_X_POWER_OFF:
i4RetValue = kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) *pIdx, false, CAMERA_HW_DRVNAME);
break;
#endif
case KDIMGSENSORIOC_X_SET_DRIVER:
i4RetValue = kdSetDriver((unsigned int*)pBuff);
break;
case KDIMGSENSORIOC_T_OPEN:
i4RetValue = adopt_CAMERA_HW_Open();
break;
case KDIMGSENSORIOC_X_GETINFO:
i4RetValue = adopt_CAMERA_HW_GetInfo(pBuff);
break;
case KDIMGSENSORIOC_X_GETRESOLUTION:
i4RetValue = adopt_CAMERA_HW_GetResolution(pBuff);
break;
case KDIMGSENSORIOC_X_FEATURECONCTROL:
i4RetValue = adopt_CAMERA_HW_FeatureControl(pBuff);
break;
case KDIMGSENSORIOC_X_CONTROL:
i4RetValue = adopt_CAMERA_HW_Control(pBuff);
break;
case KDIMGSENSORIOC_T_CLOSE:
i4RetValue = adopt_CAMERA_HW_Close();
break;
case KDIMGSENSORIOC_T_CHECK_IS_ALIVE:
i4RetValue = adopt_CAMERA_HW_CheckIsAlive();
break;
case KDIMGSENSORIOC_X_GET_SOCKET_POS:
i4RetValue = kdGetSocketPostion((unsigned int*)pBuff);
break;
case KDIMGSENSORIOC_X_SET_I2CBUS:
//i4RetValue = kdSetI2CBusNum(*pIdx);
break;
case KDIMGSENSORIOC_X_RELEASE_I2C_TRIGGER_LOCK:
//i4RetValue = kdReleaseI2CTriggerLock();
break;
default :
PK_DBG("No such command\n");
i4RetValue = -EPERM;
break;
}
if(_IOC_READ & _IOC_DIR(a_u4Command)) {
if(copy_to_user((void __user *) a_u4Param , pBuff , _IOC_SIZE(a_u4Command))) {
kfree(pBuff);
PK_DBG("[CAMERA SENSOR] ioctl copy to user failed\n");
i4RetValue = -EFAULT;
goto CAMERA_HW_Ioctl_EXIT;
}
}
kfree(pBuff);
CAMERA_HW_Ioctl_EXIT:
mutex_unlock(&kdCam_Mutex);
return i4RetValue;
}
2. Camera HAL
JNI用的接口是client提供的,Client与camera service建立连接,与service进行通信(binder机制),接
口的实现是android命名空间实现的,是由HAL层提供。HAL层的数据来源于内核驱动的上报,或者是上层下传过来
的。在设定参数时,通过Ioctl与下层交互。
HAL层提供的接口:
mediatek/hardware/camera/client/CamClient/CamClient.h
namespace android {
namespace NSCamClient {
/******************************************************************************
* Camera Client Callback Handler.
*******************************************************************************
class CamClient : public ICamClient
{
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// IClientCallback Interfaces.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public:
virtual bool init();
virtual bool uninit();
virtual bool setImgBufProviderClient(
spconst& rpClient
);
virtual void setCallbacks(sp const& rpCamMsgCbInfo);
virtual void enableMsgType(int32_t msgType);
virtual void disableMsgType(int32_t msgType);
virtual bool msgTypeEnabled(int32_t msgType);
virtual bool startPreview();
virtual void stopPreview();
virtual void takePicture();
virtual bool startRecording();
virtual void stopRecording();
virtual void releaseRecordingFrame(const void *opaque);
virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
virtual status_t dump(int fd, Vector& args);
public: Instantiation.
//
CamClient(sp pParamsMgr);
virtual ~CamClient();
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Data Members.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
protected: Common Info.
mutable Mutex mModuleMtx;
// Pointer to Camera Message-Callback Info.
sp mpCamMsgCbInfo;
// Pointer to Parameters Manager.
sp mpParamsMgr;
// Pointer to the client of Image Buffer Provider (i.e. a client is a provider-IF user of IImgBufQueue).
sp mpImgBufPvdrClient;
protected: Clients.
sp mpPreviewClient;
sp mpRecordClient;
sp mpFDClient;
sp mpPreviewFeatureClient;
};
}; // namespace NSCamClient
}; // namespace android
3. Camera JNI
该层一般是提供JAVA与 C\C++ 之间通信,这一层主要用来做一些基本的逻辑控制处理,该层主要是通过映
射表来描述 JAVA 方法与 C\C++ 函数之间的对应关系。
Camera JNI提供的接口:
frameworks/base/core/jni/
static JNINativeMethod camMethods[] = {
{ "getNumberOfCameras",
"()I",
(void *)android_hardware_Camera_getNumberOfCameras },
{ "_getCameraInfo",
"(ILandroid/hardware/Camera$CameraInfo;)V",
(void*)android_hardware_Camera_getCameraInfo },s
{ "native_setup",
"(Ljava/lang/Object;I)V",
(void*)android_hardware_Camera_native_setup },
{ "native_release",
"()V",
(void*)android_hardware_Camera_release },
{ "setPreviewDisplay",
"(Landroid/view/Surface;)V",
(void *)android_hardware_Camera_setPreviewDisplay },
{ "setPreviewTexture",
"(Landroid/graphics/SurfaceTexture;)V",
(void *)android_hardware_Camera_setPreviewTexture },
{ "startPreview",
"()V",
(void *)android_hardware_Camera_startPreview },
{ "_stopPreview",
"()V",
(void *)android_hardware_Camera_stopPreview },
.
.
.
}
4. Camera Server
camera运行时大致分为client与service两部分,分别在两个进程中运行,它们之间通过binder机制
通信。调用client端接口,功能在service端实现。
frameworks/av/services/camera/libcameraservice/CameraService.cpp
5.manged server(java)
通过Manger管理server,ServiceManager.getService()得到一个service。
frameworks/base/core/java/android/hardware/Camera.java
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
6.System server
这个主要是供其他 APP 通过 aidl 接口调用到 Server 方法,Server 方法通过JNI映射表,调用JNI的函数。进
一步封装接口,实现必要的逻辑处理。
frameworks/base/services/java/com/android/server/SystemServer.java
try {
Slog.i(TAG, "Audio Service");
ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));
} catch (Throwable e) {
reportWtf("starting Audio Service", e);
}
aidl:frameworks/base/core/java/android/os
该文件用来生成 Stub 接口文件,用来声明在 Server 提供的接口。
7.Camera APP
APP 通过获取aidl通信,获取服务,通过服务调用服务提供的类,然后调用JNI接口、JNI再去调用驱动。
packages/apps/Camera/src/com/android/camera/