getCameraInfo(i,cameraInfo);
if(cameraInfo.facing==CameraInfo.CAMERA_FACING_BACK){
returnnewCamera(i);
}
}
returnnull;
}
第5行,通过getNumberOfCameras函数来获取Camera的个数。
从上一篇博文CameraService的启动流程可以看出,这个信息保存在CameraService中。
第10行,需重点关注,构造一个Camera对象,并将它返回给app层。
3.1getNumberOfCameras函数分析
getNumberOfCameras函数进入到CameraService获取Camera个数的流程如下:
Camera.Java调用的getNumberOfCameras函数是一个JNI接口,对应的函数是android_hardware_Camera.cpp里的android_hardware_Camera_getNumberOfCameras函数
[cpp]viewplaincopy
staticjintandroid_hardware_Camera_getNumberOfCameras(JNIEnv*env,jobjectthiz)
{
returnCamera:
:
getNumberOfCameras();
}
这里只是简单调用了Camera.cpp的getNumberOfCameras函数,Camera继承了CameraBase,该函数由它实现
[cpp]viewplaincopy
template
intCameraBase:
:
getNumberOfCameras(){
constspcs=getCameraService();
returncs->getNumberOfCameras();
}
第3行,getCameraService函数用来获取ICameraService的Bp端,代码实现如下
[cpp]viewplaincopy
constchar*kCameraServiceName="media.camera";
template
constsp&CameraBase:
:
getCameraService()
{
if(gCameraService.get()==0){
spsm=defaultServiceManager();
spbinder;
binder=sm->getService(String16(kCameraServiceName));
gCameraService=interface_cast(binder);
}
returngCameraService;
}
Android的Binder通讯机制
第1行,获取的ServiceName为"media.camera",结合上一篇博文CameraService的启动流程可以看出Bn端的实现在CameraService.cpp
回到之前的getNumberOfCameras函数,在获取到ICameraService的Bp端后,就可以开始和Bn端通讯了。
在第4行,当调用cs->getNumberOfCameras函数时,将会进入CameraService.cpp的getNumberOfCameras函数
[cpp]viewplaincopy
int32_tCameraService:
:
getNumberOfCameras(){
returnmNumberOfCameras;
}
代码很简单,返回上一篇博文讲到的,千辛万苦从hal层拿到的数据
3.2Camera构造函数分析
回到最开始的Camera.open函数,在第10行,将会构造一个Camera对象
[cpp]viewplaincopy
privateintcameraInitVersion(intcameraId,inthalVersion){
......
Looperlooper;
if((looper=Looper.myLooper())!
=null){
mEventHandler=newEventHandler(this,looper);
}elseif((looper=Looper.getMainLooper())!
=null){
mEventHandler=newEventHandler(this,looper);
}else{
mEventHandler=null;
}
StringpackageName=ActivityThread.currentPackageName();
returnnative_setup(newWeakReference(this),cameraId,halVersion,packageName);
}
privateintcameraInitNormal(intcameraId){
returncameraInitVersion(cameraId,CAMERA_HAL_API_VERSION_NORMAL_CONNECT);
}
Camera(intcameraId){
interr=cameraInitNormal(cameraId);
......
}
第14行,native_setup同样是个JNI接口,对应android_hardware_Camera.cpp里的android_hardware_Camera_native_setup函数
[cpp]viewplaincopy
staticjintandroid_hardware_Camera_native_setup(JNIEnv*env,jobjectthiz,
jobjectweak_this,jintcameraId,jinthalVersion,jstringclientPackageName)
{
camera=Camera:
:
connect(cameraId,clientName,Camera:
:
USE_CALLING_UID);
#if1//defined(MTK_CAMERA_BSP_SUPPORT)
spcontext=newMtkJNICameraContext(env,weak_this,clazz,camera);
#else
spcontext=newJNICameraContext(env,weak_this,clazz,camera);
#endif
}
第4行,调用了Camera.cpp的connect函数,同时返回一个Camera对象,保存在JNICameraContext当中
[cpp]viewplaincopy
spCamera:
:
connect(intcameraId,constString16&clientPackageName,
intclientUid)
{
returnCameraBaseT:
:
connect(cameraId,clientPackageName,clientUid);
}
先来看看Camera和CameraBase的类定义
[cpp]viewplaincopy
/*----------Camera.h----------*/
template<>
structCameraTraits
{
......
staticTCamConnectServicefnConnectService;
};
classCamera:
publicCameraBase
{
......
}
/*--------CameraBase.h--------*/
template
structCameraTraits{
};
template>
classCameraBase
{
......
typedefCameraBaseCameraBaseT;
}
这里使用了C++模版,其实就是调用CameraBase:
:
connect函数
[cpp]viewplaincopy
CameraTraits:
:
TCamConnectServiceCameraTraits:
:
fnConnectService=&ICameraService:
:
connect;
template
spCameraBase:
:
connect(intcameraId,
constString16&clientPackageName,
intclientUid)
{
spc=newTCam(cameraId);
spcl=c;
constsp&cs=getCameraService();
if(cs!
=0){
TCamConnectServicefnConnectService=TCamTraits:
:
fnConnectService;
status=(cs.get()->*fnConnectService)(cl,cameraId,clientPackageName,clientUid,
/*out*/c->mCamera);
}
returnc;
}
第1行,将CameraTraits:
:
fnConnectService赋为ICameraService:
:
connect
第7行,构造一个Camera对象
第10行,获取ICameraService的Bp端
第13行,从上面的解释可以看出,实际就是调用CameraService.cpp的connect函数
第17行,将Camera对象返回给JNI层
[cpp]viewplaincopy
status_tCameraService:
:
connectHelperLocked(
/*out*/
sp&client,
/*in*/
constsp&cameraClient,
intcameraId,
constString16&clientPackageName,
intclientUid,
intcallingPid,
inthalVersion,
boollegacyMode){
......
intdeviceVersion=getDeviceVersion(cameraId,&facing);
switch(deviceVersion){
caseCAMERA_DEVICE_API_VERSION_1_0:
client=newCameraClient(this,cameraClient,
clientPackageName,cameraId,
facing,callingPid,clientUid,getpid(),legacyMode);
break;
caseCAMERA_DEVICE_API_VERSION_2_0:
caseCAMERA_DEVICE_API_VERSION_2_1:
caseCAMERA_DEVICE_API_VERSION_3_0:
caseCAMERA_DEVICE_API_VERSION_3_1:
caseCAMERA_DEVICE_API_VERSION_3_2:
client=newCamera2Client(this,cameraClient,
clientPackageName,cameraId,
facing,callingPid,clientUid,getpid(),legacyMode);
break;
}
status_tstatus=connectFinishUnsafe(client,client->getRemote());
mClient[cameraId]=client;
}
status_tCameraService:
:
connect(
constsp&cameraClient,
intcameraId,
constString16&clientPackageName,
intclientUid,
/*out*/
sp&device){
......
spclient;
status=connectHelperLocked(/*out*/client,
cameraClient,
cameraId,
clientPackageName,
clientUid,
callingPid);
device=client;
returnOK;
}
忽略细节之后connect函数就只是调用connectHelperLocked函数
第13行,获取api版本信息,这个函数比较简单,不细说。
这里的版本为CAMERA_DEVICE_API_VERSION_1_0
第15-30行,根据不同的api版本选择构造CameraClient或Camera2Client,这里是CameraClient
第32行,调用connectFinishUnsafe函数,实现如下
[cpp]viewplaincopy
status_tCameraService:
:
connectFinishUnsafe(constsp&client,
constsp&remoteCallback){
status_tstatus=client->initialize(mModule);
}
这里的client就是上一个函数的CameraClient,mModule就是在上一篇博文CameraService的启动流程里提到的hal层的接口
[cpp]viewplaincopy
status_tCameraClient:
:
initialize(camera_module_t*module){
mHardware=newCameraHardwareInterface(camera_device_name);
res=mHardware->initialize(&module->common);
mHardware->setCallbacks(notifyCallback,
dataCallback,
dataCallbackTimestamp,
(void*)(uintptr_t)mCameraId);
returnOK;
}
构造一个CameraHardwareInterface对象,并调用它的initalize函数,直接看initalize函数
[cpp]viewplaincopy
status_tinitialize(hw_module_t*module)
{
module->methods->open(module,mName.string(),(hw_device_t**)&mDevice)
initHalPreviewWindow();
}
第4行,从这里进入到了hal层,hal层主要对Camera硬件进行初始化,并将操作集保存在mDevice当中
4.hal层-基于MTK平台
hal层对Camera硬件进行初始化以及返回Device操作集的流程如下
4.1open函数分析
这里再看一次module的定义
[cpp]viewplaincopy
static
hw_module_methods_t*
get_module_methods()
{
static
hw_module_methods_t
_methods=
{
open:
open_device
};
return&_methods;
}
static
camera_module
get_camera_module()
{
camera_modulemodule={
common:
{
tag:
HARDWARE_MODULE_TAG,
#if(PLATFORM_SDK_VERSION>=21)
module_api_version:
CAMERA_MODULE_API_VERSION_2_3,
#else
module_api_version:
CAMERA_DEVICE_API_VERSION_1_0,
#endif
hal_api_version:
HARDWARE_HAL_API_VERSION,
id:
CAMERA_HARDWARE_MODULE_ID,
name:
"MediaTekCameraModule",
author:
"MediaTek",
methods:
get_module_methods(),
dso:
NULL,
reserved:
{0},
},
get_number_of_cameras:
get_number_of_cameras,
get_camera_info:
get_camera_info,
set_callbacks:
set_callbacks,
get_vendor_tag_ops:
get_vendor_tag_ops,
#if(PLATFORM_SDK_VERSION>=21)
open_legacy:
open_legacy,
#endif
reserved:
{0},
};
returnmodule;
};
通过module->methods获取到的函数为open_device,
[cpp]viewplaincopy
static
int
open_device(hw_module_tconst*module,constchar*name,hw_device_t**device)
{
returnNSCam:
:
getCamDeviceManager()->open(device,module,name);
}
CamDeviceManagerImp继承了CamDeviceManagerBase。
这里直接调用了CamDeviceManagerBase的open()
[cpp]viewplaincopy
status_t
CamDeviceManagerBase:
:
openDeviceLocked(
hw_device_t**device,
hw_module_tconst*modul